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

Revision 497, 10.0 KB checked in by mattausch, 19 years ago (diff)

beware: bug in view cells merging

  • 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
8#include <GL/glext.h>
9
10GlRendererWidget *rendererWidget = NULL;
11
12#ifdef _WIN32
13PFNGLGENOCCLUSIONQUERIESNVPROC glGenOcclusionQueriesNV;
14PFNGLBEGINOCCLUSIONQUERYNVPROC glBeginOcclusionQueryNV;
15PFNGLENDOCCLUSIONQUERYNVPROC glEndOcclusionQueryNV;
16PFNGLGETOCCLUSIONQUERYUIVNVPROC glGetOcclusionQueryuivNV;
17#endif
18
19GlRenderer::GlRenderer(SceneGraph *sceneGraph,
20                                           ViewCellsManager *viewCellsManager):
21  Renderer(sceneGraph, viewCellsManager)
22{
23  mSceneGraph->CollectObjects(&mObjects);
24  mViewPoint = mSceneGraph->GetBox().Center();
25  mViewDirection = Vector3(0,0,1);
26  //  timerId = startTimer(10);
27  mFrame = 0;
28}
29
30GlRenderer::~GlRenderer()
31{
32}
33
34void
35GlRenderer::RenderIntersectable(Intersectable *object)
36{
37
38  SetupFalseColor(object->mId);
39
40  switch (object->Type()) {
41  case Intersectable::MESH_INSTANCE:
42        RenderMeshInstance((MeshInstance *)object);
43        break;
44  default:
45        cerr<<"Rendering this object not yet implemented\n";
46        break;
47  }
48}
49
50
51void
52GlRenderer::RenderMeshInstance(MeshInstance *mi)
53{
54  RenderMesh(mi->GetMesh());
55}
56
57void
58GlRenderer::SetupFalseColor(const int id)
59{
60  // swap bits of the color
61 
62  glColor3ub(id&255, (id>>8)&255, (id>>16)&255);
63}
64
65void
66GlRenderer::SetupMaterial(Material *m)
67{
68  if (m)
69        glColor3fv(&(m->mDiffuseColor.r));
70  else
71        glColor3f(1.0f, 1.0f, 1.0f);
72}
73
74void
75GlRenderer::RenderMesh(Mesh *mesh)
76{
77  int i = 0;
78
79  if (!mUseFalseColors)
80        SetupMaterial(mesh->mMaterial);
81 
82  for (i=0; i < mesh->mFaces.size(); i++) {
83        glBegin(GL_POLYGON);
84        Face *face = mesh->mFaces[i];
85        for (int j = 0; j < face->mVertexIndices.size(); j++) {
86          glVertex3fv(&mesh->mVertices[face->mVertexIndices[j]].x);
87        }
88        glEnd();
89  }
90}
91       
92void
93GlRenderer::InitGL()
94{
95  glMatrixMode(GL_PROJECTION);
96  glLoadIdentity();
97 
98  glMatrixMode(GL_MODELVIEW);
99  glLoadIdentity();
100
101  glEnable(GL_CULL_FACE);
102  glShadeModel(GL_FLAT);
103  glEnable(GL_DEPTH_TEST);
104  glEnable(GL_CULL_FACE);
105 
106  glGenOcclusionQueriesNV = (PFNGLGENOCCLUSIONQUERIESNVPROC)
107        wglGetProcAddress("glGenOcclusionQueriesNV");
108  glBeginOcclusionQueryNV = (PFNGLBEGINOCCLUSIONQUERYNVPROC)
109        wglGetProcAddress("glBeginOcclusionQueryNV");
110  glEndOcclusionQueryNV = (PFNGLENDOCCLUSIONQUERYNVPROC)
111        wglGetProcAddress("glEndOcclusionQueryNV");
112  glGetOcclusionQueryuivNV = (PFNGLGETOCCLUSIONQUERYUIVNVPROC)
113        wglGetProcAddress("glGetOcclusionQueryuivNV");
114}
115
116
117
118void
119GlRenderer::SetupProjection(const int w, const int h)
120{
121  glViewport(0, 0, w, h);
122  glMatrixMode(GL_PROJECTION);
123  glLoadIdentity();
124  gluPerspective(70.0, 1.0, 0.1, 2.0*Magnitude(mSceneGraph->GetBox().Diagonal()));
125  glMatrixMode(GL_MODELVIEW);
126}
127
128void
129GlRenderer::SetupCamera()
130{
131  Vector3 target = mViewPoint + mViewDirection;
132  Vector3 up(0,1,0);
133 
134  glLoadIdentity();
135  gluLookAt(mViewPoint.x, mViewPoint.y, mViewPoint.z,
136                        target.x, target.y, target.z,
137                        up.x, up.y, up.z);
138}
139
140void
141GlRenderer::RandomViewPoint()
142{
143  Vector3 pVector = Vector3(halton.GetNumber(1),
144                                                        halton.GetNumber(2),
145                                                        halton.GetNumber(3));
146 
147  Vector3 dVector = Vector3(2*M_PI*halton.GetNumber(4),
148                                                        M_PI*halton.GetNumber(5),
149                                                        0.0f);
150 
151  mViewPoint = mSceneGraph->GetBox().GetPoint(pVector);
152 
153  mViewDirection = Normalize(Vector3(sin(dVector.x),
154                                                                         //                                                                      cos(dVector.y),
155                                                                         0.0f,
156                                                                         cos(dVector.x)));
157
158  halton.GenerateNext();
159}
160
161
162float
163GlRenderer::GetPixelError()
164{
165  float pErrorPixels = -1.0f;
166
167  glReadBuffer(GL_BACK);
168 
169  mUseFalseColors = true;
170
171  SetupCamera();
172  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
173  glEnable( GL_CULL_FACE );
174 
175  RenderScene();
176
177  // now check whether any backfacing polygon would pass the depth test
178  static int query = -1;
179  if (query == -1)
180        glGenOcclusionQueriesNV(1, (unsigned int *)&query);
181 
182  glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
183  glDepthMask(GL_FALSE);
184  glDisable( GL_CULL_FACE );
185 
186  glBeginOcclusionQueryNV(query);
187 
188  RenderScene();
189 
190  glEndOcclusionQueryNV();
191
192  // at this point, if possible, go and do some other computation
193  glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
194  glDepthMask(GL_TRUE);
195  glEnable( GL_CULL_FACE );
196 
197  unsigned int pixelCount;
198  // reenable other state
199  glGetOcclusionQueryuivNV(query,
200                                                   GL_PIXEL_COUNT_NV,
201                                                   &pixelCount);
202
203  if (pixelCount > 0)
204        return -1.0f; // backfacing polygon found -> not a valid viewspace sample
205
206  ViewCell *viewcell = mViewCellsManager->GetViewCell(mViewPoint);
207 
208  if (viewcell) {
209        SetupCamera();
210        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
211
212        // Render PVS
213        std::map<Intersectable *,
214          PvsData<Intersectable *>,
215          LtSample<Intersectable *> >::const_iterator it = viewcell->GetPvs().mEntries.begin();
216       
217        for (; it != viewcell->GetPvs().mEntries.end(); ++ it) {
218          Intersectable *object = (*it).first;
219          RenderIntersectable(object);
220        }
221
222        glBeginOcclusionQueryNV(query);
223
224        SetupCamera();
225
226        RenderScene();
227       
228        glEndOcclusionQueryNV();
229       
230
231        unsigned int pixelCount;
232        // reenable other state
233        glGetOcclusionQueryuivNV(query,
234                                                         GL_PIXEL_COUNT_NV,
235                                                         &pixelCount);
236       
237        pErrorPixels = (100.f*pixelCount)/(GetWidth()*GetHeight());
238  }
239 
240  return pErrorPixels;
241}
242
243
244float
245GlRendererWidget::RenderErrors()
246{
247  float pErrorPixels = -1.0f;
248
249  glReadBuffer(GL_BACK);
250 
251  mUseFalseColors = true;
252
253  SetupCamera();
254  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
255  glEnable( GL_CULL_FACE );
256 
257  ObjectContainer::const_iterator oi = mObjects.begin();
258  for (; oi != mObjects.end(); oi++)
259        RenderIntersectable(*oi);
260
261  ViewCell *viewcell = mViewCellsManager->GetViewCell(mViewPoint);
262 
263  QImage im1, im2;
264  QImage diff;
265 
266  if (viewcell) {
267        // read back the texture
268        im1 = grabFrameBuffer(true);
269       
270        SetupCamera();
271        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
272       
273        std::map<Intersectable *,
274          PvsData<Intersectable *>,
275          LtSample<Intersectable *> >::const_iterator it = viewcell->GetPvs().mEntries.begin();
276       
277        for (; it != viewcell->GetPvs().mEntries.end(); ++ it) {
278          Intersectable *object = (*it).first;
279          RenderIntersectable(object);
280        }
281
282        // read back the texture
283        im2 = grabFrameBuffer(true);
284       
285        diff = im1;
286        int x, y;
287        int errorPixels = 0;
288       
289        for (y = 0; y < im1.height(); y++)
290          for (x = 0; x < im1.width(); x++)
291                if (im1.pixel(x, y) == im2.pixel(x, y))
292                  diff.setPixel(x, y, qRgba(0,0,0,0));
293                else {
294                  diff.setPixel(x, y, qRgba(255,128,128,255));
295                  errorPixels++;
296                }
297        pErrorPixels = (100.f*errorPixels)/(im1.height()*im1.width());
298  }
299
300  // now render the pvs again
301  SetupCamera();
302  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
303  mUseFalseColors = false;
304       
305  oi = mObjects.begin();
306  for (; oi != mObjects.end(); oi++)
307        RenderIntersectable(*oi);
308
309  // now render im1
310  if (viewcell) {
311        // init ortographic projection
312        glMatrixMode(GL_PROJECTION);
313        glPushMatrix();
314       
315        glLoadIdentity();
316        gluOrtho2D(0, 1.0f, 0, 1.0f);
317       
318        glMatrixMode(GL_MODELVIEW);
319        glLoadIdentity();
320       
321        bindTexture(diff);
322       
323        glPushAttrib(GL_ENABLE_BIT);
324        glEnable( GL_ALPHA_TEST );
325        glDisable( GL_CULL_FACE );
326        glAlphaFunc( GL_GREATER, 0.5 );
327       
328        glEnable( GL_TEXTURE_2D );
329        glBegin(GL_QUADS);
330       
331        glTexCoord2f(0,0);
332        glVertex3f(0,0,0);
333       
334        glTexCoord2f(1,0);
335        glVertex3f( 1, 0, 0);
336       
337        glTexCoord2f(1,1);
338        glVertex3f( 1, 1, 0);
339       
340        glTexCoord2f(0,1);
341        glVertex3f(0, 1, 0);
342        glEnd();
343       
344        glPopAttrib();
345       
346        // restore the projection matrix
347        glMatrixMode(GL_PROJECTION);
348        glPopMatrix();
349        glMatrixMode(GL_MODELVIEW);
350  }
351
352  return pErrorPixels;
353}
354
355
356bool
357GlRenderer::RenderScene()
358{
359  static int glList = -1;
360  if (glList != -1) {
361        glCallList(glList);
362  } else {
363        glList = glGenLists(1);
364        glNewList(glList, GL_COMPILE_AND_EXECUTE);
365        ObjectContainer::const_iterator oi = mObjects.begin();
366        for (; oi != mObjects.end(); oi++)
367          RenderIntersectable(*oi);
368        glEndList();
369  }
370  return true;
371}
372
373
374void
375GlRendererBuffer::ClearErrorBuffer()
376{
377  for (int i=0; i < mPvsStatFrames; i++) {
378        mPvsErrorBuffer[i] = 1.0f;
379  }
380}
381
382
383void
384GlRendererBuffer::EvalPvsStat()
385{
386  mPvsStat.Reset();
387  halton.Reset();
388
389  makeCurrent();
390
391  SetupProjection(GetWidth(), GetHeight());
392 
393  for (int i=0; i < mPvsStatFrames; i++) {
394        float err;
395        RandomViewPoint();
396        if (mPvsErrorBuffer[i] > 0.0f) {
397          mPvsErrorBuffer[i] = GetPixelError();
398          cout<<"("<<i<<","<<mPvsErrorBuffer[i]<<")";
399          //      swapBuffers();
400        }
401       
402        err = mPvsErrorBuffer[i];
403       
404        if (err >= 0.0f) {
405          if (err > mPvsStat.maxError)
406                mPvsStat.maxError = err;
407          mPvsStat.sumError += err;
408          if (err == 0.0f)
409                mPvsStat.errorFreeFrames++;
410          mPvsStat.frames++;
411        }
412  }
413 
414  doneCurrent();
415
416  cout<<endl<<flush;
417  mRenderingFinished.wakeAll();
418}
419
420
421
422
423
424void
425GlRendererWidget::mousePressEvent(QMouseEvent *e)
426{
427  int x = e->pos().x();
428  int y = e->pos().y();
429
430  mousePoint.x = x;
431  mousePoint.y = y;
432 
433}
434
435void
436GlRendererWidget::mouseMoveEvent(QMouseEvent *e)
437{
438  float MOVE_SENSITIVITY = Magnitude(mSceneGraph->GetBox().Diagonal())*1e-3;
439  float TURN_SENSITIVITY=0.1f;
440  float TILT_SENSITIVITY=32.0 ;
441  float TURN_ANGLE= M_PI/36.0 ;
442
443  int x = e->pos().x();
444  int y = e->pos().y();
445 
446  if (e->modifiers() & Qt::ControlModifier) {
447        mViewPoint.y += (y-mousePoint.y)*MOVE_SENSITIVITY/2.0;
448        mViewPoint.x += (x-mousePoint.x)*MOVE_SENSITIVITY/2.0;
449  } else {
450        mViewPoint += mViewDirection*((mousePoint.y - y)*MOVE_SENSITIVITY);
451        float adiff = TURN_ANGLE*(x - mousePoint.x)*-TURN_SENSITIVITY;
452        float angle = atan2(mViewDirection.x, mViewDirection.z);
453        mViewDirection.x = sin(angle+adiff);
454        mViewDirection.z = cos(angle+adiff);
455  }
456 
457  mousePoint.x = x;
458  mousePoint.y = y;
459 
460  updateGL();
461}
462
463void
464GlRendererWidget::mouseReleaseEvent(QMouseEvent *)
465{
466
467
468}
469
470void
471GlRendererWidget::resizeGL(int w, int h)
472{
473  SetupProjection(w, h);
474  updateGL();
475}
476
477void
478GlRendererWidget::paintGL()
479{
480  RenderErrors();
481  mFrame++;
482}
Note: See TracBrowser for help on using the repository browser.