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

Revision 502, 10.2 KB checked in by bittner, 19 years ago (diff)

bsp viewcell location

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