QtBaseViewer.cc 75 KB
Newer Older
Jan Möbius's avatar
Jan Möbius committed
1
2
3
/*===========================================================================*\
*                                                                            *
*                              OpenFlipper                                   *
Martin Schultz's avatar
Martin Schultz committed
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 *           Copyright (c) 2001-2015, RWTH-Aachen University                 *
 *           Department of Computer Graphics and Multimedia                  *
 *                          All rights reserved.                             *
 *                            www.openflipper.org                            *
 *                                                                           *
 *---------------------------------------------------------------------------*
 * This file is part of OpenFlipper.                                         *
 *---------------------------------------------------------------------------*
 *                                                                           *
 * Redistribution and use in source and binary forms, with or without        *
 * modification, are permitted provided that the following conditions        *
 * are met:                                                                  *
 *                                                                           *
 * 1. Redistributions of source code must retain the above copyright notice, *
 *    this list of conditions and the following disclaimer.                  *
 *                                                                           *
 * 2. Redistributions in binary form must reproduce the above copyright      *
 *    notice, this list of conditions and the following disclaimer in the    *
 *    documentation and/or other materials provided with the distribution.   *
 *                                                                           *
 * 3. Neither the name of the copyright holder nor the names of its          *
 *    contributors may be used to endorse or promote products derived from   *
 *    this software without specific prior written permission.               *
 *                                                                           *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       *
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A           *
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  *
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,       *
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR        *
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    *
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      *
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        *
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              *
Jan Möbius's avatar
Jan Möbius committed
39
*                                                                            *
40
41
42
\*===========================================================================*/

/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
43
44
45
46
47
*                                                                            *
*   $Revision$                                                       *
*   $LastChangedBy$                                                *
*   $Date$                     *
*                                                                            *
48
\*===========================================================================*/
Jan Möbius's avatar
   
Jan Möbius committed
49
50
51
52
53
54




//=============================================================================
//
Jan Möbius's avatar
   
Jan Möbius committed
55
//  CLASS glViewer - IMPLEMENTATION
Jan Möbius's avatar
   
Jan Möbius committed
56
57
58
59
60
61
//
//=============================================================================


//== INCLUDES =================================================================

Christopher Tenter's avatar
Christopher Tenter committed
62
63
#include <ACG/GL/acg_glew.hh>

Jan Möbius's avatar
   
Jan Möbius committed
64
#include "QtBaseViewer.hh"
Jan Möbius's avatar
Jan Möbius committed
65
#include "QtGLViewerLayout.hh"
Christopher Tenter's avatar
Christopher Tenter committed
66
#include "PostProcessing.hh"
Jan Möbius's avatar
Jan Möbius committed
67

Jan Möbius's avatar
   
Jan Möbius committed
68
#include <ACG/QtWidgets/QtWheel.hh>
69
#include <ACG/Scenegraph/CoordsysNode.hh>
Jan Möbius's avatar
Jan Möbius committed
70
#include <ACG/Scenegraph/SceneGraphAnalysis.hh>
71
#include <ACG/GL/GLError.hh>
72
#include <ACG/GL/IRenderer.hh>
Jan Möbius's avatar
   
Jan Möbius committed
73

Martin Schultz's avatar
Martin Schultz committed
74
75
#include <QGraphicsWidget>
#include <QString>
Hans-Christian Ebke's avatar
Hans-Christian Ebke committed
76
77
78
79
80
81
#include <QBoxLayout>
#include <QtNetwork/QUdpSocket>
#include <QToolBar>
#include <QGraphicsSceneDragDropEvent>
#include <QPropertyAnimation>

Jan Möbius's avatar
   
Jan Möbius committed
82
83
84
85
86
87
88
#include <QMimeData>

#include <QClipboard>
#include <QApplication>
#include <QSplitter>
#include <QColorDialog>

89
#include <QGraphicsView>
Jan Möbius's avatar
   
Jan Möbius committed
90
91
#include <QGraphicsProxyWidget>

92
93
#include <QImageWriter>

94
#if QT_VERSION < 0x050000
Hans-Christian Ebke's avatar
Hans-Christian Ebke committed
95
#include <QGLFramebufferObject>
96
97
98
#else
#include <QOpenGLFramebufferObject>
#endif
99

Jan Möbius's avatar
   
Jan Möbius committed
100
101
102
103
104
105
106
107
#ifdef max
#  undef max
#endif

#ifdef min
#  undef min
#endif

108
#include <OpenFlipper/BasePlugin/PluginFunctions.hh>
Jan Möbius's avatar
Jan Möbius committed
109
#include <OpenFlipper/common/ViewObjectMarker.hh>
Jan Möbius's avatar
   
Jan Möbius committed
110

Jan Möbius's avatar
Dennis:    
Jan Möbius committed
111
112
#include <OpenFlipper/common/GlobalOptions.hh>

113
#include <OpenFlipper/common/RendererInfo.hh>
114

Jan Möbius's avatar
   
Jan Möbius committed
115
116
117
118
119
120
//== NAMESPACES ===============================================================



//== IMPLEMENTATION ==========================================================

121
static const char          COPY_PASTE_VIEW_START_STRING[] =
Jan Möbius's avatar
   
Jan Möbius committed
122
123
124
125
126
  "ACG::QtWidgets::QGLViewerWidget encoded view";

//== IMPLEMENTATION ==========================================================


127
glViewer::glViewer( QGraphicsScene* _scene,
128
                    OFGLWidget* _glWidget,
129
                    Viewer::ViewerProperties& _properties,
130
                    QGraphicsWidget* _parent) :
Jan Möbius's avatar
   
Jan Möbius committed
131
  QGraphicsWidget(_parent),
Jan Möbius's avatar
   
Jan Möbius committed
132
133
  glareaGrabbed_(false),
  projectionUpdateLocked_(false),
Jan Möbius's avatar
   
Jan Möbius committed
134
135
  glScene_(_scene),
  glWidget_(_glWidget),
Jan Möbius's avatar
Jan Möbius committed
136
137
138
  pickCache_(0),
  updatePickCache_(true),
  pickCacheSupported_(true),
139
  constrainedRotationAxis_(std::numeric_limits<double>::quiet_NaN(), 0, 0),
140
  clickEvent_(QEvent::MouseButtonPress, QPoint (), Qt::NoButton, Qt::NoButton, Qt::NoModifier),
Dirk Wilden's avatar
Dirk Wilden committed
141
  properties_(_properties),
142
  glstate_(0),
Jan Möbius's avatar
Jan Möbius committed
143
144
145
146
147
  initialized_(false),
  flyAnimationPerspective_(0),
  flyAnimationOrthogonal_(0),
  flyAngle_(0.0),
  currentAnimationPos_(0.0),
Christopher Tenter's avatar
Christopher Tenter committed
148
149
  flyMoveBack_(false),
  postproc_(0)
Jan Möbius's avatar
   
Jan Möbius committed
150
151
152
{

  // widget stuff
153
  createWidgets();
Jan Möbius's avatar
   
Jan Möbius committed
154
155
156

  // bind GL context to GL state class
  glstate_ = new ACG::GLState();
157
158
  properties_.setglState( glstate_ );

Jan Möbius's avatar
   
Jan Möbius committed
159
160
  // state
  isRotating_       = false;
Mike Kremer's avatar
Mike Kremer committed
161
  lookAround_       = false;
Jan Möbius's avatar
   
Jan Möbius committed
162
163
164

  sceneGraphRoot_   = 0;

165
  normalsMode_      = NORMALIZE_NORMALS;
Jan Möbius's avatar
   
Jan Möbius committed
166
  projectionMode_   = PERSPECTIVE_PROJECTION;
Jan Möbius's avatar
Jan Möbius committed
167
  navigationMode_   = NORMAL_NAVIGATION;
168

Jan Möbius's avatar
   
Jan Möbius committed
169
170
171
172
173
174
175
176
177
178
179
180
181
182
  trackMouse_ = false;

  // Note: we start locked (initialization of updateLocked_)
  // will be unlocked in initializeGL()

  QSizePolicy sp = sizePolicy();
  sp.setHorizontalPolicy( QSizePolicy::Expanding );
  sp.setVerticalPolicy( QSizePolicy::Expanding );
  sp.setHorizontalStretch( 1 );
  sp.setVerticalStretch( 1 );
  setSizePolicy( sp );

  redrawTime_.start ();

183
184
185
186
  // timer for animation
  timer_ = new QTimer( this );
  connect( timer_, SIGNAL(timeout()), this, SLOT( slotAnimation()) );

187
188
  fovyModifier_ = 1.0;

189
190
191
  allowRotation_ = true;


Jan Möbius's avatar
   
Jan Möbius committed
192
193
194
  connect( &properties_,SIGNAL(updated()), this, SLOT( slotPropertiesUpdated() ) );


Dirk Wilden's avatar
Dirk Wilden committed
195
196
197
  //check for updated properties once
  slotPropertiesUpdated();

Jan Möbius's avatar
   
Jan Möbius committed
198
  setAcceptDrops(true);
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
199

200
  setHome();
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
201

202
203
  clickTimer_.setSingleShot (true);
  connect (&clickTimer_, SIGNAL(timeout ()), this, SLOT(slotClickTimeout ()));
Jan Möbius's avatar
   
Jan Möbius committed
204
205
206
207
208
209
}


//-----------------------------------------------------------------------------


Jan Möbius's avatar
   
Jan Möbius committed
210
glViewer::~glViewer()
Jan Möbius's avatar
   
Jan Möbius committed
211
212
213
214
215
216
217
218
{
  delete glstate_;
}


//-----------------------------------------------------------------------------


219
220
221
222
223
//QSizeF
//glViewer::sizeHint(Qt::SizeHint which, const QSizeF & constraint) const
//{
//  return QSizeF( 600, 600 );
//}
Jan Möbius's avatar
   
Jan Möbius committed
224
225
226
227

//-----------------------------------------------------------------------------


Jan Möbius's avatar
   
Jan Möbius committed
228
void glViewer::makeCurrent() {
Jan Möbius's avatar
   
Jan Möbius committed
229
230
231
232
233
234
  glWidget_->makeCurrent();
}


//-----------------------------------------------------------------------------

Jan Möbius's avatar
Jan Möbius committed
235
236
237
238
239
void glViewer::sceneGraph(ACG::SceneGraph::BaseNode* _root,
                          unsigned int               _maxPasses,
                          ACG::Vec3d                 _bbmin,
                          ACG::Vec3d                 _bbmax,
                          const bool _resetTrackBall)
Jan Möbius's avatar
   
Jan Möbius committed
240
241
242
{
  sceneGraphRoot_ = _root;

Jan Möbius's avatar
Jan Möbius committed
243
  if (sceneGraphRoot_ )
Jan Möbius's avatar
   
Jan Möbius committed
244
245
  {

Jan Möbius's avatar
Jan Möbius committed
246
247
    // set max number of render pass
    glstate_->set_max_render_passes(_maxPasses);
Jan Möbius's avatar
Jan Möbius committed
248
    
Jan Möbius's avatar
Jan Möbius committed
249
250
251
    if ( ( _bbmin[0] > _bbmax[0] ) ||
         ( _bbmin[1] > _bbmax[1] ) ||
         ( _bbmin[2] > _bbmax[2] )   ) {
252
253
      
      // Invalid bounding box, try to recover
254
      setScenePos( properties_.sceneCenter() , properties_.sceneRadius(), _resetTrackBall );
255
256
    
      // Update bounding box to match the scene geometry after recovery
Jan Möbius's avatar
Jan Möbius committed
257
258
      _bbmin = ACG::Vec3d(-1.0,-1.0,-1.0);
      _bbmax = ACG::Vec3d( 1.0, 1.0, 1.0);
Jan Möbius's avatar
Jan Möbius committed
259
260
    } else {
      
261
      // For very small scenes, we set the scene radius to 0.1
Jan Möbius's avatar
Jan Möbius committed
262
      // otherwise we take the real radius
Jan Möbius's avatar
Jan Möbius committed
263
264
      if ( ( _bbmax - _bbmin ).max() < OpenFlipperSettings().value("Core/Gui/glViewer/minimalSceneSize",0.1).toDouble() )  {
        setScenePos( ( _bbmin + _bbmax )        * 0.5,
265
                     OpenFlipperSettings().value("Core/Gui/glViewer/minimalSceneSize",0.1).toDouble(),
Jan Möbius's avatar
Jan Möbius committed
266
267
268
                     _resetTrackBall);
                   
      } else {
Jan Möbius's avatar
Jan Möbius committed
269
270
        setScenePos( ( _bbmin + _bbmax )        * 0.5,
                     ( _bbmax - _bbmin ).norm() * 0.5,
Jan Möbius's avatar
Jan Möbius committed
271
272
273
274
                     _resetTrackBall); 
      }
                   
    }
275
276
                   
    // remember the new bounding box for the state
Jan Möbius's avatar
Jan Möbius committed
277
    glstate_->set_bounding_box(_bbmin,_bbmax);
278
    
Jan Möbius's avatar
   
Jan Möbius committed
279
  }
280
  
Jan Möbius's avatar
   
Jan Möbius committed
281
282
283
284
285
286
287
288
289
290

  updateGL();

  emit(signalSceneGraphChanged(sceneGraphRoot_));
}


//-----------------------------------------------------------------------------


Jan Möbius's avatar
   
Jan Möbius committed
291
void glViewer::trackMouse(bool _track)
Jan Möbius's avatar
   
Jan Möbius committed
292
293
294
295
296
297
298
{
  trackMouse_ = _track;
}


//-----------------------------------------------------------------------------

299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
void glViewer::setCoordSysProjection(ProjectionMode _mode) {
  // Find coordsys node
  ACG::SceneGraph::BaseNode* node = 0;
  node = PluginFunctions::getSceneGraphRootNode()->find("Core Coordsys Node");

  // set the projection mode for the coordinate system node
  if (node != 0) {
    ACG::SceneGraph::CoordsysNode* cnode = dynamic_cast<ACG::SceneGraph::CoordsysNode*> (node);
    if (_mode ==  ORTHOGRAPHIC_PROJECTION) {
      cnode->setProjectionMode(ACG::SceneGraph::CoordsysNode::ORTHOGRAPHIC_PROJECTION);
    } else {
      cnode->setProjectionMode(ACG::SceneGraph::CoordsysNode::PERSPECTIVE_PROJECTION);
    }
  }
}


//-----------------------------------------------------------------------------


Jan Möbius's avatar
   
Jan Möbius committed
319
void glViewer::perspectiveProjection()
Jan Möbius's avatar
   
Jan Möbius committed
320
321
322
323
324
325
{
  projectionMode(PERSPECTIVE_PROJECTION);
  updateGL();
}


Jan Möbius's avatar
   
Jan Möbius committed
326
void glViewer::orthographicProjection()
Jan Möbius's avatar
   
Jan Möbius committed
327
328
329
330
331
332
{
  projectionMode(ORTHOGRAPHIC_PROJECTION);
  updateGL();
}


Jan Möbius's avatar
   
Jan Möbius committed
333
void glViewer::toggleProjectionMode()
Jan Möbius's avatar
   
Jan Möbius committed
334
335
336
337
338
339
340
341
342
343
{
  if (projectionMode_ == ORTHOGRAPHIC_PROJECTION)
    projectionMode(PERSPECTIVE_PROJECTION);
  else
    projectionMode(ORTHOGRAPHIC_PROJECTION);

  updateGL();
}


Jan Möbius's avatar
   
Jan Möbius committed
344
void glViewer::projectionMode(ProjectionMode _p)
Jan Möbius's avatar
   
Jan Möbius committed
345
346
{
  if ((projectionMode_ = _p) == ORTHOGRAPHIC_PROJECTION)
347
    emit projectionModeChanged( true );
Jan Möbius's avatar
   
Jan Möbius committed
348
  else
349
    emit projectionModeChanged( false );
Jan Möbius's avatar
   
Jan Möbius committed
350
351

  updateProjectionMatrix();
352

353
354
  setCoordSysProjection(_p);

355
  emit viewChanged();
Jan Möbius's avatar
   
Jan Möbius committed
356
357
}

358
359
360
void glViewer::toggleNavigationMode()
{
  if (navigationMode_ == NORMAL_NAVIGATION)
Mike Kremer's avatar
Mike Kremer committed
361
    navigationMode(FIRSTPERSON_NAVIGATION);
362
363
364
365
366
367
368
369
370
371
372
373
374
  else
    navigationMode(NORMAL_NAVIGATION);
}


void glViewer::navigationMode(NavigationMode _n)
{
  if ((navigationMode_ = _n) == NORMAL_NAVIGATION)
    emit navigationModeChanged( true );
  else
    emit navigationModeChanged( false );
}

375
376
377
378
379
380
381
382
383
384
385
void glViewer::setFOVY(double _fovy) {
    
  if(_fovy <= 0.0 || _fovy >= 180) {
    std::cerr << "Error: Minimum or maximum fovy angle exceeded!" << std::endl;
    return;
  }
  
  OpenFlipperSettings().setValue("Core/Projection/FOVY", _fovy);
  updateProjectionMatrix();
}

386
void glViewer::updateProjectionMatrix(double _aspect)
Jan Möbius's avatar
   
Jan Möbius committed
387
388
389
390
391
392
393
394
{
  if( projectionUpdateLocked_ )
    return;

  makeCurrent();

  glstate_->reset_projection();

395
  const double aspect = _aspect ? _aspect : this->aspect_ratio();
396
  // In stereo mode we have to use a perspective matrix
397
  if ( projectionMode_ == PERSPECTIVE_PROJECTION)
Jan Möbius's avatar
   
Jan Möbius committed
398
  {
399

400
    // Get fovy
401
    const double fovy = this->field_of_view_vertical();
402
403

    glstate_->perspective(fovy, (GLdouble) aspect,
404
                          near_plane(), far_plane());
Jan Möbius's avatar
Jan Möbius committed
405
406
407
  }
  else
  {
Jan Möbius's avatar
   
Jan Möbius committed
408

409
410
411
    glstate_->ortho( -ortho_width(), ortho_width(),
                     -ortho_width() / aspect, ortho_width() / aspect,
                     near_plane(), far_plane() );
Jan Möbius's avatar
   
Jan Möbius committed
412
  }
413

Jan Möbius's avatar
   
Jan Möbius committed
414
415
416
417
418
419
}


//-----------------------------------------------------------------------------


420
void glViewer::setScenePos(const ACG::Vec3d& _center, double _radius, const bool _resetTrackBall)
Jan Möbius's avatar
   
Jan Möbius committed
421
{
422
  if(_resetTrackBall) {
423
    properties_.trackballCenter(_center);
424
425
  }

426
  properties_.sceneCenter(_center);
427

428
429
  properties_.sceneRadius(_radius);
  properties_.trackballRadius(_radius);
430

431
  ACG::Vec3d c = glstate_->modelview().transform_point(properties_.sceneCenter());
432

Jan Möbius's avatar
Jan Möbius committed
433
434
  double nearPlane = std::max(0.0001f * properties_.sceneRadius(),  -(c[2] + properties_.sceneRadius()));
  double farPlane  = std::max(0.0002f * properties_.sceneRadius(),  -(c[2] - properties_.sceneRadius()));
435
436

   // Safety check, if near < 0
Jan Möbius's avatar
Jan Möbius committed
437
   if ( nearPlane <= 0.0 ) {
438
     std::cerr << "Error in BaseViewer drawScene, nearplane <= 0.0" << std::endl;
Jan Möbius's avatar
Jan Möbius committed
439
     nearPlane = 0.000000000000001;
440
441
442
   }

  // Safety check. Make sure that they are in the right order
Jan Möbius's avatar
Typo    
Jan Möbius committed
443
  if ( nearPlane > farPlane ) {
444
    std::cerr << "Error in BaseViewer setScenePos, Nearplane > Farplane" << std::endl;
Jan Möbius's avatar
Jan Möbius committed
445
    std::swap(nearPlane,farPlane);
446
447
  }

Jan Möbius's avatar
Jan Möbius committed
448
  properties_.setPlanes(nearPlane,farPlane);
Jan Möbius's avatar
   
Jan Möbius committed
449

450
451
452
453
  updateProjectionMatrix();
  updateGL();

  emit viewChanged();
454
455
456
457
458
459
}


//----------------------------------------------------------------------------


Jan Möbius's avatar
   
Jan Möbius committed
460
void glViewer::viewingDirection( const ACG::Vec3d& _dir, const ACG::Vec3d& _up )
Jan Möbius's avatar
   
Jan Möbius committed
461
462
{
  // calc eye point for this direction
463
  ACG::Vec3d eye = properties_.sceneCenter() - _dir * ( 3.0 * properties_.sceneRadius());
Jan Möbius's avatar
   
Jan Möbius committed
464
465

  glstate_->reset_modelview();
466
  glstate_->lookAt((ACG::Vec3d)eye, (ACG::Vec3d)properties_.sceneCenter(), (ACG::Vec3d)_up);
467

468
  emit viewChanged();
Jan Möbius's avatar
   
Jan Möbius committed
469
470
}

471
472
473
474
475
476
477
//-----------------------------------------------------------------------------

void glViewer::lookAt(const ACG::Vec3d& _eye, const ACG::Vec3d& _center, const ACG::Vec3d& _up) {
    
    glstate_->reset_modelview();
    glstate_->lookAt(_eye, _center, _up);
    
478
479
    properties_.sceneCenter( _center );
    properties_.sceneRadius( (properties_.sceneCenter() - _eye).norm() );
480
481
482
    
    emit viewChanged();
}
Jan Möbius's avatar
   
Jan Möbius committed
483
484
485

//-----------------------------------------------------------------------------

Jan Möbius's avatar
   
Jan Möbius committed
486
void glViewer::normalsMode(NormalsMode _mode)
Jan Möbius's avatar
   
Jan Möbius committed
487
488
489
490
491
492
{
  makeCurrent();

  switch(normalsMode_ = _mode)
  {
    case DONT_TOUCH_NORMALS:
493
      ACG::GLState::disable(GL_NORMALIZE);
Jan Möbius's avatar
   
Jan Möbius committed
494
495
496
      break;

    case NORMALIZE_NORMALS:
497
      ACG::GLState::enable(GL_NORMALIZE);
Jan Möbius's avatar
   
Jan Möbius committed
498
499
500
501
502
503
504
505
506
507
508
      break;
  }

  updateGL();
}


//-----------------------------------------------------------------------------


void
Jan Möbius's avatar
   
Jan Möbius committed
509
glViewer::copyToImage( QImage& _image,
Jan Möbius's avatar
Jan Möbius committed
510
511
		       unsigned int _l, unsigned int _t,
		       unsigned int _w, unsigned int _h,
512
			     GLenum /* _buffer */ )
Jan Möbius's avatar
   
Jan Möbius committed
513
{
514
515
516

//    makeCurrent();

517
#if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 4))
518
519
520
521
522
  _image = glWidget_->grabFramebuffer()
#else
  _image = glWidget_->grabFrameBuffer(true)
#endif
    .copy(_l, _t, _w, _h).convertToFormat(QImage::Format_RGB32);
Jan Möbius's avatar
   
Jan Möbius committed
523
524
525
526
527
528
}


//-----------------------------------------------------------------------------


Jan Möbius's avatar
   
Jan Möbius committed
529
void glViewer::updateGL()
Jan Möbius's avatar
   
Jan Möbius committed
530
{
Jan Möbius's avatar
   
Jan Möbius committed
531
  if (!properties_.updateLocked() && isVisible() )
Jan Möbius's avatar
   
Jan Möbius committed
532
  {
Jan Möbius's avatar
Jan Möbius committed
533
    updatePickCache_ = true;
Jan Möbius's avatar
   
Jan Möbius committed
534
    update();
535
536

    emit viewUpdated();
Jan Möbius's avatar
   
Jan Möbius committed
537
538
539
540
541
542
543
544
  }
}



//-----------------------------------------------------------------------------


545
void glViewer::drawScene(double _aspect)
Jan Möbius's avatar
   
Jan Möbius committed
546
{
547
548
549
550
  
  // Inside the glWidget rendering, the system should not send extra updates
  properties_.blockSignals(true);
  
Jan Möbius's avatar
   
Jan Möbius committed
551
552
553
  QTime  timer;
  timer.start();

Jan Möbius's avatar
   
Jan Möbius committed
554
555
556
557
  // *****************************************************************
  // Adjust clipping planes
  // *****************************************************************
  // Far plane
558
  ACG::Vec3d c = glstate_->modelview().transform_point(properties_.sceneCenter());
Jan Möbius's avatar
   
Jan Möbius committed
559

Jan Möbius's avatar
Jan Möbius committed
560
561
  double nearPlane = std::max(0.0001f * properties_.sceneRadius(),  -(c[2] + properties_.sceneRadius()));
  double farPlane  = std::max(0.0002f * properties_.sceneRadius(),  -(c[2] - properties_.sceneRadius()));
562
563

  // Safety check, if near < 0
Jan Möbius's avatar
Jan Möbius committed
564
  if ( nearPlane <= 0.0 ) {
565
    std::cerr << "Error in BaseViewer drawScene, nearplane < 0" << std::endl;
Jan Möbius's avatar
Jan Möbius committed
566
    nearPlane = 0.000000000000001;
567
568
569
  }

  // Safety check. Make sure that they are in the right order
Jan Möbius's avatar
Jan Möbius committed
570
  if ( nearPlane > farPlane ) {
571
    std::cerr << "Error in BaseViewer drawScene, Nearplane > Farplane" << std::endl;
Jan Möbius's avatar
Jan Möbius committed
572
    std::swap(nearPlane,farPlane);
573
  }
Jan Möbius's avatar
   
Jan Möbius committed
574

Jan Möbius's avatar
Jan Möbius committed
575
  properties_.setPlanes(nearPlane,farPlane);
Jan Möbius's avatar
   
Jan Möbius committed
576

577
  updateProjectionMatrix(_aspect);
Jan Möbius's avatar
   
Jan Möbius committed
578
579
580
581
582

  // store time since last repaint in gl state and restart timer
  glstate_->set_msSinceLastRedraw (redrawTime_.restart ());

  makeCurrent();
583

Jan Möbius's avatar
Jan Möbius committed
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
  // draw mono or stereo
  // If stereo mode is selected, we have to provide multiple ways of rendering.

  // 1. Default internal pipeline : Directly to output buffer (no stereo support!)
  // 2. Non default : Non-stereo Directly to output buffer (no stereo support!)
  //
  //

//  if (OpenFlipper::Options::stereoMode () == OpenFlipper::Options::OpenGL && OpenFlipper::Options::glStereo ())
//  {
//    // Stereo      : Hardware support (OpenGL stereo : left and right buffer with offset eyes)
//
//    return;
//  }
//  else if (OpenFlipper::Options::stereoMode () == OpenFlipper::Options::AnaglyphCustom && customAnaglyphSupported_)
//  {
//    //Stereo      : No Hardware support (Left and right frame buffer with offset eyes)
//  } else {
//
//  }

605
606
607
608
609
610
611
  // save hardware backbuffer
  GLuint backbufferFbo = 0;
  GLuint backbufferTarget = 0;
  glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, (GLint*)&backbufferFbo);
  glGetIntegerv(GL_DRAW_BUFFER, (GLint*)&backbufferTarget);


Christopher Tenter's avatar
Christopher Tenter committed
612

613
  // Render plugins do not have to worry about using scissor test for clearing their viewports later on.
614
  glClearColor(properties_.backgroundColor()[0], properties_.backgroundColor()[1],
Christopher Tenter's avatar
Christopher Tenter committed
615
    properties_.backgroundColor()[2], properties_.backgroundColor()[3]);
616
617
618
619
620
621
622
  GLint curViewport[4];
  glGetIntegerv(GL_VIEWPORT, curViewport);
  glScissor(curViewport[0], curViewport[1], curViewport[2], curViewport[3]);
  glEnable(GL_SCISSOR_TEST);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glDisable(GL_SCISSOR_TEST);

Jan Möbius's avatar
Jan Möbius committed
623

Christopher Tenter's avatar
Christopher Tenter committed
624
625
626
627
628

  // setup scene target fbo
  if (!postproc_)
    postproc_ = new PostProcessing();

Christopher Tenter's avatar
Christopher Tenter committed
629
630
631
632
  const int numPostProcessors = postProcessorManager().numActive(properties_.viewerId());

  bool stereoOpenGL = false;
  bool stereoAnaglyph = false;
633
634
635
  ACG::GLMatrixd projSave = glstate_->projection();
  ACG::GLMatrixd projLR[2];

Christopher Tenter's avatar
Christopher Tenter committed
636
637
638
  if (properties_.stereo()) {
    stereoOpenGL = OpenFlipper::Options::stereoMode () == OpenFlipper::Options::OpenGL && OpenFlipper::Options::glStereo ();
    stereoAnaglyph = !stereoOpenGL;
639
    computeProjStereo(glstate_->viewport_width(), glstate_->viewport_height(), properties_, projLR, projLR+1);
Christopher Tenter's avatar
Christopher Tenter committed
640
641
  }

Christopher Tenter's avatar
Christopher Tenter committed
642
643
644
645
646
647
648
649
650
  if (!stereoOpenGL && !stereoAnaglyph)
  {
    // setup render target fbo
    postproc_->setupScene(properties_.viewerId(), glstate_->viewport_width(), glstate_->viewport_height(),
      properties_.multisampling() ? 16 : 0, -1);
  }



651
  // Check if we use build in default renderer
Jan Möbius's avatar
Jan Möbius committed
652
  if ( renderManager().activeId( properties_.viewerId() ) == 0 ) {
653
    drawScene_mono();
Jan Möbius's avatar
Jan Möbius committed
654
  } else {
655
656
657
658
659
660
661
662
    RenderInterface* renderPlugin = renderManager().active( properties_.viewerId() )->plugin;

    // eventually set viewer id in IRenderer
    ACG::IRenderer* shaderRenderPlugin = dynamic_cast<ACG::IRenderer*>(renderPlugin);

    if (shaderRenderPlugin)
      shaderRenderPlugin->setViewerID( properties_.viewerId() );

Christopher Tenter's avatar
Christopher Tenter committed
663
    if (stereoOpenGL || stereoAnaglyph) {
Christopher Tenter's avatar
Christopher Tenter committed
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
      // save current fbo
      GLuint backbufferFbo = 0;
      GLuint backbufferTarget = 0;
      glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, (GLint*)&backbufferFbo);
      glGetIntegerv(GL_DRAW_BUFFER, (GLint*)&backbufferTarget);

      // setup stereo rendering

      // left eye: fbo 0
      // right eye: fbo 1

      for (int eye = 0; eye < 2; ++eye) {

        glstate_->set_projection(projLR[eye]);
        if (stereoOpenGL && !numPostProcessors) {
          // render directly into back_left
          glDrawBuffer(eye ? GL_BACK_RIGHT : GL_BACK_LEFT);
Christopher Tenter's avatar
Christopher Tenter committed
681
682
683
          glEnable(GL_SCISSOR_TEST);
          glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
          glDisable(GL_SCISSOR_TEST);
Christopher Tenter's avatar
Christopher Tenter committed
684
685
        }
        else {
Christopher Tenter's avatar
Christopher Tenter committed
686
687
          postproc_->setupScene(properties_.viewerId(), glstate_->viewport_width(), glstate_->viewport_height(),
            properties_.multisampling() ? 16 : 0, eye);
Christopher Tenter's avatar
Christopher Tenter committed
688
        }
Christopher Tenter's avatar
Christopher Tenter committed
689
        
Christopher Tenter's avatar
Christopher Tenter committed
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
        renderPlugin->render(glstate_,properties_);
        drawCursor();
      }

      // restore projection
      glstate_->set_projection(projSave);

      // restore backbuffer
      glBindFramebuffer(GL_FRAMEBUFFER, backbufferFbo);
      glDrawBuffer(backbufferTarget);
    }
    else {
      renderPlugin->render(glstate_,properties_);
      drawCursor();
    }
Jan Möbius's avatar
Jan Möbius committed
705
  }
706
  checkGLError();
Jan Möbius's avatar
Jan Möbius committed
707
708


709
710
  // =================================================================================
  // Post-Processing pipeline
Jan Möbius's avatar
Jan Möbius committed
711
712


Christopher Tenter's avatar
Christopher Tenter committed
713
714
715
716
717
718
  postproc_->postProcess(properties_.viewerId(),
    glstate_,
    glstate_->modelview(),
    (stereoOpenGL || stereoAnaglyph) ? projLR[0] : glstate_->projection(),
    projLR[1],
    stereoOpenGL);
Jan Möbius's avatar
Jan Möbius committed
719

Christopher Tenter's avatar
Christopher Tenter committed
720
721
  if (stereoAnaglyph)
    postproc_->resolveStereoAnyglyph(properties_.viewerId());
Jan Möbius's avatar
Jan Möbius committed
722
723

  // =================================================================================
724
  glBindFramebuffer(GL_FRAMEBUFFER, backbufferFbo);
725
  glDrawBuffer(backbufferTarget);
Jan Möbius's avatar
Jan Möbius committed
726
  // unbind vbo for qt log window
Hans-Christian Ebke's avatar
Hans-Christian Ebke committed
727
728
729
  ACG::GLState::bindBuffer(GL_ARRAY_BUFFER, 0);
  ACG::GLState::activeTexture(GL_TEXTURE0);
  ACG::GLState::bindTexture(GL_TEXTURE_2D, 0);
Jan Möbius's avatar
Jan Möbius committed
730
731
732
733
734
735
736
737
738
//  fbo.release();
//
//  QRect blitRect(0,0,glstate_->viewport_width(),glstate_->viewport_height());
//
//  //
//  //QTime time;
//  //time.restart();
//  QGLFramebufferObject::blitFramebuffer( 0 , blitRect, &fbo, blitRect , GL_COLOR_BUFFER_BIT );
//  //std::cerr << "Elapsed for blit: " << time.elapsed() << std::endl;
Jan Möbius's avatar
   
Jan Möbius committed
739
  glFinish();
Jan Möbius's avatar
Jan Möbius committed
740

Jan Möbius's avatar
   
Jan Möbius committed
741
  frame_time_ = timer.elapsed();
Jan Möbius's avatar
Jan Möbius committed
742

743
744
745
  
  // Inside the glWidget rendering, the system should not send extra updates
  properties_.blockSignals(false);
Jan Möbius's avatar
   
Jan Möbius committed
746
747
748
749
750
751
}


//-----------------------------------------------------------------------------


Jan Möbius's avatar
   
Jan Möbius committed
752
void glViewer::drawScene_mono()
Jan Möbius's avatar
   
Jan Möbius committed
753
{
754
755
756
757
  if (sceneGraphRoot_) {
    ViewObjectMarker *oM = properties_.objectMarker();
    GLuint refBits = 0;
    QSet<GLuint> references;
758

759
760
761
    if (oM)
    {
      glClear (GL_STENCIL_BUFFER_BIT);
762
      ACG::GLState::enable (GL_STENCIL_TEST);
763
764
      glStencilOp (GL_KEEP, GL_KEEP, GL_ZERO);
      glStencilFunc (GL_ALWAYS, 0, ~0);
765

766
767
      for (PluginFunctions::ObjectIterator o_it(PluginFunctions::ALL_OBJECTS, DATA_ALL) ;
          o_it != PluginFunctions::objectsEnd(); ++o_it)
768
      {
769
770
771
772
        bool ok;
        GLuint ref;

        ok = oM->stencilRefForObject(*o_it, ref);
773

774
        if (ok)
775
        {
776
777
778
779
          o_it->stencilRefNode ()->setReference (ref);
          o_it->stencilRefNode ()->show ();
          refBits |= ref;
          references << ref;
780
        }
781
782
        else
          o_it->stencilRefNode ()->hide ();
783
      }
784
785
    }

Jan Möbius's avatar
Jan Möbius committed
786
787
788
    // First pass
    ACG::SceneGraph::DrawAction pass1( properties_.drawMode(), *glstate_ , false);
    ACG::SceneGraph::traverse_multipass(sceneGraphRoot_, pass1, *glstate_, properties_.drawMode() );
789

Jan Möbius's avatar
Jan Möbius committed
790
791
792
    // Second Pass for Blending operations
    ACG::SceneGraph::DrawAction pass2(properties_.drawMode(), *glstate_, true);
    ACG::SceneGraph::traverse_multipass(sceneGraphRoot_, pass2, *glstate_, properties_.drawMode());
Jan Möbius's avatar
   
Jan Möbius committed
793

794
795
796
    if (oM)
    {
      if (oM->type() == ViewObjectMarker::PerBit)
Jan Möbius's avatar
   
Jan Möbius committed
797
      {
798
799
800
801
        references.clear ();
        for (unsigned int i = 0; i < sizeof (GLuint) * 8; i++)
          if (refBits & (1 << i))
            references << (1 << i);
Jan Möbius's avatar
   
Jan Möbius committed
802
      }
803

804
      glPushAttrib(GL_ALL_ATTRIB_BITS);
805

806
      ACG::GLState::enable(GL_BLEND);
807
808
809
      ACG::GLState::disable(GL_DEPTH_TEST);
      ACG::GLState::disable(GL_LIGHTING);
      ACG::GLState::disable(GL_DITHER);
810

811
812
      int vp_l, vp_b, vp_w, vp_h;
      glstate_->get_viewport (vp_l, vp_b, vp_w, vp_h);
813

814
815
816
817
818
819
820
      glMatrixMode(GL_PROJECTION);
      glPushMatrix ();
      glLoadIdentity();
      glOrtho(0, vp_w, vp_h, 0, 0, 1.0);
      glMatrixMode(GL_MODELVIEW);
      glPushMatrix ();
      glLoadIdentity();
821

822
      glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
823

824
825
826
827
828
829
830
      foreach (unsigned int ref, references)
      {
        bool ok;
        GLenum sfactor;
        GLenum dfactor;
        ACG::Vec4f color;
        unsigned int mask = ~0;
831

832
        if (oM->type() == ViewObjectMarker::PerBit)
833
        {
834
835
          ok = oM->blendForStencilRefBit (ref, sfactor, dfactor, color);
          mask = ref;
836
        }
837
838
        else
          ok = oM->blendForStencilRefNumber (ref, sfactor, dfactor, color);
839

840
841
        if (!ok)
          continue;
842

843
        glStencilFunc (GL_EQUAL, ref, mask);
Jan Möbius's avatar
   
Jan Möbius committed
844

845
        ACG::GLState::blendFunc (sfactor, dfactor);
846
        glColor4f (color[0], color [1], color [2], color[3]);
Jan Möbius's avatar
   
Jan Möbius committed
847

848
849
850
851
852
853
854
855
        glBegin (GL_QUADS);
        glVertex2i(0, 0);
        glVertex2i(0, vp_h);
        glVertex2i(vp_w, vp_h);
        glVertex2i(vp_w, 0);
        glEnd ();

      }
Jan Möbius's avatar
   
Jan Möbius committed
856

857
858
859
860
      glMatrixMode(GL_PROJECTION);
      glPopMatrix ();
      glMatrixMode(GL_MODELVIEW);
      glPopMatrix ();
Jan Möbius's avatar
   
Jan Möbius committed
861

862
      glPopAttrib ();
863
      ACG::GLState::disable (GL_STENCIL_TEST);
Jan Möbius's avatar
   
Jan Möbius committed
864
    }
865
866


Jan Möbius's avatar
   
Jan Möbius committed
867
  }
Jan Möbius's avatar
Jan Möbius committed
868

Christopher Tenter's avatar
Christopher Tenter committed
869
870
871
872
873
874
875
  drawCursor();

}


void glViewer::drawCursor()
{
876
  if (properties_.cursorPainter() && properties_.cursorPainter()->enabled () && properties_.cursorPositionValid() )
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
877
878
879
880
881
  {
    glstate_->push_modelview_matrix ();
    // reset view transformation
    glstate_->reset_modelview ();
    // translate cursor position to 0,0
882
    glstate_->translate ( properties_.cursorPoint3D() );
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
883
    // paint cursor
884
    properties_.cursorPainter()->paintCursor (glstate_);
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
885
886
    glstate_->pop_modelview_matrix ();
  }
Jan Möbius's avatar
   
Jan Möbius committed
887
888
}

Christopher Tenter's avatar
Christopher Tenter committed
889

Jan Möbius's avatar
   
Jan Möbius committed
890
void glViewer::setHome()
Jan Möbius's avatar
   
Jan Möbius committed
891
892
893
{
  home_modelview_          = glstate_->modelview();
  home_inverse_modelview_  = glstate_->inverse_modelview();
894
  homeOrthoWidth_          = properties_.orthoWidth();
895
896
  home_center_             = properties_.trackballCenter();
  home_radius_             = properties_.trackballRadius();
Jan Möbius's avatar
   
Jan Möbius committed
897
898
899
}


Jan Möbius's avatar
   
Jan Möbius committed
900
void glViewer::home()
Jan Möbius's avatar
   
Jan Möbius committed
901
902
903
{
  makeCurrent();
  glstate_->set_modelview(home_modelview_, home_inverse_modelview_);
904
  properties_.orthoWidth( homeOrthoWidth_ );
905
906
  properties_.trackballCenter( home_center_ );
  properties_.trackballRadius(home_radius_);
Jan Möbius's avatar
   
Jan Möbius committed
907
908
  updateProjectionMatrix();
  updateGL();
909

910
  emit viewChanged();
Jan Möbius's avatar
   
Jan Möbius committed
911
912
913
914
915

}

//-----------------------------------------------------------------------------

Jan Möbius's avatar
   
Jan Möbius committed
916
void glViewer::viewAll()
Jan Möbius's avatar
   
Jan Möbius committed
917
{
918
919
920
  makeCurrent();
  // update scene graph (get new bounding box and set projection right, including near and far plane)
  properties_.lockUpdate();
Jan Möbius's avatar
   
Jan Möbius committed
921

922
923
924
925
926
927
928
929
930
931
  unsigned int maxPases = 1;
  ACG::Vec3d bbmin,bbmax;
  // update scene bounding boxes
  ACG::SceneGraph::analyzeSceneGraph(PluginFunctions::getSceneGraphRootNode(),maxPases,bbmin,bbmax);

  // update scene properties (near, far plane, scene radius according to the computed bounding boxes)
  sceneGraph ( PluginFunctions::getSceneGraphRootNode(), maxPases,bbmin,bbmax,true);


  // update camera
932
933
934
  // move center (in camera coords) to origin and translate in -z dir
  translate(-(glstate_->modelview().transform_point(properties_.sceneCenter()))
            - ACG::Vec3d(0.0, 0.0, 3.0 * properties_.sceneRadius()));
935

936
937
938
939
  properties_.orthoWidth( 1.1 * properties_.sceneRadius() );
  double aspect = (double) glWidth() / (double) glHeight();
  if (aspect > 1.0)
    properties_.orthoWidth( aspect * properties_.orthoWidth() ) ;
940

941
942
943
  properties_.unLockUpdate();
  updateProjectionMatrix();
  updateGL();
944

945
  emit viewChanged();
Jan Möbius's avatar
   
Jan Möbius committed
946
947
948
949
950
951
952

}


//-----------------------------------------------------------------------------


Jan Möbius's avatar
   
Jan Möbius committed
953
void glViewer::setView(const ACG::GLMatrixd& _modelview,
Jan Möbius's avatar
   
Jan Möbius committed
954
955
956
957
958
			                  const ACG::GLMatrixd& _inverse_modelview)
{
  makeCurrent();
  glstate_->set_modelview(_modelview, _inverse_modelview);
  updateGL();
959

960
  emit viewChanged();
Jan Möbius's avatar
   
Jan Möbius committed
961
962
963
964
965
966
}


//-----------------------------------------------------------------------------


Jan Möbius's avatar
   
Jan Möbius committed
967
void glViewer::initializeGL()
Jan Möbius's avatar
   
Jan Möbius committed
968
969
970
{

  // lock update
971
  properties_.lockUpdate();
Jan Möbius's avatar
   
Jan Möbius committed
972
973
974
975
976

  // init GL state
  glstate_->initialize();

  // OpenGL state
977
978
  ACG::GLState::enable(GL_DEPTH_TEST);
  ACG::GLState::enable(GL_LIGHTING);
979
  ACG::GLState::disable(GL_DITHER);
980
  ACG::GLState::shadeModel( GL_FLAT );
Jan Möbius's avatar
   
Jan Möbius committed
981
982
983
984
985


  projectionMode(   projectionMode_   );
  normalsMode(      normalsMode_      );

986
  // Update all settings which would require a redraw
987
  applyProperties();
Jan Möbius's avatar
   
Jan Möbius committed
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004

  // modelview
  glstate_->translate(0.0, 0.0, -3.0);
  setHome();

  // pixel transfer
  glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
  glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
  glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  glPixelStorei(GL_PACK_ROW_LENGTH, 0);
  glPixelStorei(GL_PACK_SKIP_ROWS, 0);
  glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
  glPixelStorei(GL_PACK_ALIGNMENT, 1);


  // unlock update (we started locked)
1005
  properties_.unLockUpdate();
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
1006

1007
1008
1009
1010
  initialized_ = true;

  if (sceneGraphRoot_)
  {
Jan Möbius's avatar
Jan Möbius committed
1011
1012
1013
1014
1015
1016
    unsigned int maxPases = 1;
    ACG::Vec3d bbmin,bbmax;
    ACG::SceneGraph::analyzeSceneGraph(sceneGraphRoot_,maxPases,bbmin,bbmax);

    sceneGraph ( sceneGraphRoot_, maxPases,bbmin,bbmax,true);
    viewAll();
1017
  }
Jan Möbius's avatar
   
Jan Möbius committed
1018
1019
1020
1021
1022
1023
}


//-----------------------------------------------------------------------------


1024
void glViewer::paintGL(double _aspect)
Jan Möbius's avatar
   
Jan Möbius committed
1025
{
1026
1027
  if (!initialized_)
    initializeGL ();
1028
  if (!properties_.updateLocked())
Jan Möbius's avatar
   
Jan Möbius committed
1029
  {
1030
    properties_.lockUpdate();
Jan Möbius's avatar
   
Jan Möbius committed
1031
1032
1033

    glPushAttrib (GL_ALL_ATTRIB_BITS);

1034
1035
    ACG::GLState::enable(GL_DEPTH_TEST);
    ACG::GLState::enable(GL_LIGHTING);
1036
    ACG::GLState::disable(GL_DITHER);
1037
    ACG::GLState::shadeModel( GL_FLAT );
Jan Möbius's avatar
   
Jan Möbius committed
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047

    glMatrixMode(GL_PROJECTION);
    glPushMatrix();

    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();


    normalsMode(      normalsMode_      );

1048
    applyProperties();
1049

1050
    glstate_->setState();
Jan Möbius's avatar
   
Jan Möbius committed
1051
1052
1053

    glColor4f(1.0,0.0,0.0,1.0);

1054
    glstate_->clearBuffers ();
Jan Möbius's avatar
   
Jan Möbius committed
1055

1056
    properties_.unLockUpdate();
Jan Möbius's avatar
   
Jan Möbius committed
1057
1058

    // draw scene
1059
    drawScene(_aspect);
Jan Möbius's avatar
   
Jan Möbius committed
1060
1061
1062
1063
1064
1065
1066
1067

    glPopMatrix();

    glMatrixMode(GL_PROJECTION);
    glPopMatrix();

    glPopAttrib ();
  }
1068
1069
  glBindBuffer(GL_ARRAY_BUFFER, 0);
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
Jan Möbius's avatar
   
Jan Möbius committed
1070
1071
1072
1073
1074
1075
}


//-----------------------------------------------------------------------------


Jan Möbius's avatar
   
Jan Möbius committed
1076
void glViewer::resizeEvent(QGraphicsSceneResizeEvent *)
Jan Möbius's avatar
   
Jan Möbius committed
1077
1078
{
  updateProjectionMatrix();
Jan Möbius's avatar
   
Jan Möbius committed
1079
  glstate_->viewport(scenePos().x(),
Jan Möbius's avatar
Jan Möbius committed
1080
1081
1082
                     scene()->height () - scenePos().y() - size().height (),
                     size().width (), size().height (),
                     scene()->width (), scene()->height ());
Jan Möbius's avatar
   
Jan Möbius committed
1083
  update();
1084

1085
  emit viewChanged();
Jan Möbius's avatar
   
Jan Möbius committed
1086
1087
}

Jan Möbius's avatar
   
Jan Möbius committed
1088
1089
1090
void glViewer::moveEvent (QGraphicsSceneMoveEvent *)
{
  glstate_->viewport(scenePos().x(),
Jan Möbius's avatar
Jan Möbius committed
1091
1092
1093
                     scene()->height () - scenePos().y() - size().height (),
                     size().width (), size().height (),
                     scene()->width (), scene()->height ());
Jan Möbius's avatar
   
Jan Möbius committed
1094
  update();
1095

1096
  emit viewChanged();
Jan Möbius's avatar
   
Jan Möbius committed
1097
}
Jan Möbius's avatar
   
Jan Möbius committed
1098
1099
1100

//-----------------------------------------------------------------------------

1101
1102
void glViewer::encodeView(QString& _view, const QSize& _windowSize /*= QSize()*/,
        const int _splitterWidth /*=-1*/, const bool _make_c_string /*= false*/)
Jan Möbius's avatar
   
Jan Möbius committed
1103
{
1104
  // Get current matrices
Jan Möbius's avatar
   
Jan Möbius committed
1105
1106
1107
  const ACG::GLMatrixd m = glstate_->modelview();
  const ACG::GLMatrixd p = glstate_->projection();

1108
1109
1110
1111
1112
1113
1114
  static const char *line_delim_c = " \\\n";
  static const char *line_delim_std = line_delim_c + 2;
  const char *line_delim = _make_c_string ? line_delim_c : line_delim_std;

  if (_make_c_string)
      _view += "\"";

Jan Möbius's avatar