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

Revision 494, 10.4 KB checked in by bittner, 19 years ago (diff)

changes for qt 4.1.0

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