QtBaseViewer.cc 71 KB
Newer Older
Jan Möbius's avatar
Jan Möbius committed
1
2
3
/*===========================================================================*\
*                                                                            *
*                              OpenFlipper                                   *
Jan Möbius's avatar
Jan Möbius committed
4
*      Copyright (C) 2001-2014 by Computer Graphics Group, RWTH Aachen       *
Jan Möbius's avatar
Jan Möbius committed
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
*                           www.openflipper.org                              *
*                                                                            *
*--------------------------------------------------------------------------- *
*  This file is part of OpenFlipper.                                         *
*                                                                            *
*  OpenFlipper is free software: you can redistribute it and/or modify       *
*  it under the terms of the GNU Lesser General Public License as            *
*  published by the Free Software Foundation, either version 3 of            *
*  the License, or (at your option) any later version with the               *
*  following exceptions:                                                     *
*                                                                            *
*  If other files instantiate templates or use macros                        *
*  or inline functions from this file, or you compile this file and          *
*  link it with other files to produce an executable, this file does         *
*  not by itself cause the resulting executable to be covered by the         *
*  GNU Lesser General Public License. This exception does not however        *
*  invalidate any other reasons why the executable file might be             *
*  covered by the GNU Lesser General Public License.                         *
*                                                                            *
*  OpenFlipper is distributed in the hope that it will be useful,            *
*  but WITHOUT ANY WARRANTY; without even the implied warranty of            *
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
*  GNU Lesser General Public License for more details.                       *
*                                                                            *
*  You should have received a copy of the GNU LesserGeneral Public           *
*  License along with OpenFlipper. If not,                                   *
*  see <http://www.gnu.org/licenses/>.                                       *
*                                                                            *
33
34
35
\*===========================================================================*/

/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
36
37
38
39
40
*                                                                            *
*   $Revision$                                                       *
*   $LastChangedBy$                                                *
*   $Date$                     *
*                                                                            *
41
\*===========================================================================*/
Jan Möbius's avatar
 
Jan Möbius committed
42
43
44
45
46
47




//=============================================================================
//
Jan Möbius's avatar
   
Jan Möbius committed
48
//  CLASS glViewer - IMPLEMENTATION
Jan Möbius's avatar
 
Jan Möbius committed
49
50
51
52
53
54
55
//
//=============================================================================


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

#include "QtBaseViewer.hh"
Jan Möbius's avatar
Jan Möbius committed
56
#include "QtGLViewerLayout.hh"
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
57
#include "CursorPainter.hh"
Jan Möbius's avatar
Jan Möbius committed
58

Jan Möbius's avatar
 
Jan Möbius committed
59
60
#include <ACG/QtWidgets/QtWheel.hh>
#include <ACG/Scenegraph/DrawModes.hh>
61
#include <ACG/Scenegraph/CoordsysNode.hh>
Jan Möbius's avatar
Jan Möbius committed
62
#include <ACG/Scenegraph/SceneGraphAnalysis.hh>
Jan Möbius's avatar
 
Jan Möbius committed
63
#include <ACG/GL/gl.hh>
64
65
#include <ACG/GL/GLError.hh>
#include <ACG/GL/FBO.hh>
66
#include <ACG/GL/IRenderer.hh>
Jan Möbius's avatar
 
Jan Möbius committed
67
68
69

#include <iostream>
#include <string>
70
#include <cassert>
Jan Möbius's avatar
 
Jan Möbius committed
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102

#include <QMimeData>
#include <QToolButton>
#include <QFrame>

#include <QClipboard>
#include <QApplication>
#include <QSplitter>
#include <QLayout>
#include <QPushButton>
#include <QLabel>
#include <QImage>
#include <QColorDialog>
#include <QToolTip>
#include <QTextStream>
#include <QDateTime>
#include <QTimer>

#include <QDesktopWidget>
#include <QMouseEvent>
#include <QVBoxLayout>
#include <QKeyEvent>
#include <QGridLayout>
#include <QContextMenuEvent>
#include <QWheelEvent>
#include <QDropEvent>
#include <QPixmap>
#include <QMenu>
#include <QVariant>
#include <QButtonGroup>
#include <QToolBar>

103
104
#include <QGraphicsView>
#include <QGraphicsScene>
Jan Möbius's avatar
 
Jan Möbius committed
105
106
107
#include <QGraphicsWidget>
#include <QGraphicsGridLayout>
#include <QGraphicsProxyWidget>
Jan Möbius's avatar
   
Jan Möbius committed
108
109
#include <QPainter>
#include <QPaintEngine>
Jan Möbius's avatar
 
Jan Möbius committed
110

111
112
#include <QImageWriter>

113
114
115
116
117
118
119
120
#if QT_VERSION < 0x050000
  #include <QGLFramebufferObject>
#else // QT_VERSION > 0x050000
  #undef QT_NO_OPENGL
  #include <QOpenGLFramebufferObject>
  #define QT_NO_OPENGL
#endif //QT_VERSION < 0x050000

Jan Möbius's avatar
 
Jan Möbius committed
121
122
123
124
125
126
127
128
#ifdef max
#  undef max
#endif

#ifdef min
#  undef min
#endif

129
#include <OpenFlipper/BasePlugin/PluginFunctions.hh>
Jan Möbius's avatar
Jan Möbius committed
130
#include <OpenFlipper/common/ViewObjectMarker.hh>
Jan Möbius's avatar
 
Jan Möbius committed
131

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

134
135
#include <QGLFramebufferObject>

136
#include <OpenFlipper/common/RendererInfo.hh>
137
138
#include <OpenFlipper/BasePlugin/PostProcessorInterface.hh>

Jan Möbius's avatar
 
Jan Möbius committed
139
140
141
142
143
144
//== NAMESPACES ===============================================================



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

145
static const char          COPY_PASTE_VIEW_START_STRING[] =
Jan Möbius's avatar
 
Jan Möbius committed
146
147
148
149
150
  "ACG::QtWidgets::QGLViewerWidget encoded view";

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


151
glViewer::glViewer( QGraphicsScene* _scene,
152
                    QGLWidget* _glWidget,
153
                    Viewer::ViewerProperties& _properties,
154
                    QGraphicsWidget* _parent) :
Jan Möbius's avatar
   
Jan Möbius committed
155
  QGraphicsWidget(_parent),
Jan Möbius's avatar
 
Jan Möbius committed
156
157
  glareaGrabbed_(false),
  projectionUpdateLocked_(false),
Jan Möbius's avatar
   
Jan Möbius committed
158
159
  glScene_(_scene),
  glWidget_(_glWidget),
Jan Möbius's avatar
Jan Möbius committed
160
161
162
  pickCache_(0),
  updatePickCache_(true),
  pickCacheSupported_(true),
163
  constrainedRotationAxis_(std::numeric_limits<double>::quiet_NaN(), 0, 0),
164
  clickEvent_(QEvent::MouseButtonPress, QPoint (), Qt::NoButton, Qt::NoButton, Qt::NoModifier),
Dirk Wilden's avatar
Dirk Wilden committed
165
  properties_(_properties),
166
  glstate_(0),
Jan Möbius's avatar
Jan Möbius committed
167
168
169
170
171
  initialized_(false),
  flyAnimationPerspective_(0),
  flyAnimationOrthogonal_(0),
  flyAngle_(0.0),
  currentAnimationPos_(0.0),
172
  flyMoveBack_(false)
Jan Möbius's avatar
 
Jan Möbius committed
173
174
175
{

  // widget stuff
176
  createWidgets();
Jan Möbius's avatar
 
Jan Möbius committed
177
178
179

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

Jan Möbius's avatar
 
Jan Möbius committed
182
183
  // state
  isRotating_       = false;
Mike Kremer's avatar
Mike Kremer committed
184
  lookAround_       = false;
Jan Möbius's avatar
 
Jan Möbius committed
185
186
187

  sceneGraphRoot_   = 0;

188
  normalsMode_      = NORMALIZE_NORMALS;
Jan Möbius's avatar
 
Jan Möbius committed
189
  projectionMode_   = PERSPECTIVE_PROJECTION;
Jan Möbius's avatar
Jan Möbius committed
190
  navigationMode_   = NORMAL_NAVIGATION;
191

Jan Möbius's avatar
 
Jan Möbius committed
192
193
194
195
196
197
198
199
200
201
202
203
204
205
  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 ();

206
207
208
209
  // timer for animation
  timer_ = new QTimer( this );
  connect( timer_, SIGNAL(timeout()), this, SLOT( slotAnimation()) );

210
211
  fovyModifier_ = 1.0;

212
213
214
  allowRotation_ = true;


Jan Möbius's avatar
   
Jan Möbius committed
215
216
217
  connect( &properties_,SIGNAL(updated()), this, SLOT( slotPropertiesUpdated() ) );


Dirk Wilden's avatar
Dirk Wilden committed
218
219
220
  //check for updated properties once
  slotPropertiesUpdated();

Jan Möbius's avatar
   
Jan Möbius committed
221
  setAcceptDrops(true);
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
222

223
  setHome();
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
224

225
226
  clickTimer_.setSingleShot (true);
  connect (&clickTimer_, SIGNAL(timeout ()), this, SLOT(slotClickTimeout ()));
Jan Möbius's avatar
 
Jan Möbius committed
227
228
229
230
231
232
}


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


Jan Möbius's avatar
   
Jan Möbius committed
233
glViewer::~glViewer()
Jan Möbius's avatar
 
Jan Möbius committed
234
235
236
237
238
239
240
241
{
  delete glstate_;
}


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


242
243
244
245
246
//QSizeF
//glViewer::sizeHint(Qt::SizeHint which, const QSizeF & constraint) const
//{
//  return QSizeF( 600, 600 );
//}
Jan Möbius's avatar
 
Jan Möbius committed
247
248
249
250

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


Jan Möbius's avatar
   
Jan Möbius committed
251
void glViewer::makeCurrent() {
Jan Möbius's avatar
 
Jan Möbius committed
252
253
254
  glWidget_->makeCurrent();
}

Jan Möbius's avatar
   
Jan Möbius committed
255
void glViewer::swapBuffers() {
Jan Möbius's avatar
 
Jan Möbius committed
256
257
258
259
260
261
  glWidget_->swapBuffers();
}


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

Jan Möbius's avatar
Jan Möbius committed
262
263
264
265
266
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
267
268
269
{
  sceneGraphRoot_ = _root;

Jan Möbius's avatar
Jan Möbius committed
270
  if (sceneGraphRoot_ )
Jan Möbius's avatar
 
Jan Möbius committed
271
272
  {

Jan Möbius's avatar
Jan Möbius committed
273
274
    // set max number of render pass
    glstate_->set_max_render_passes(_maxPasses);
Jan Möbius's avatar
Jan Möbius committed
275
    
Jan Möbius's avatar
Jan Möbius committed
276
277
278
    if ( ( _bbmin[0] > _bbmax[0] ) ||
         ( _bbmin[1] > _bbmax[1] ) ||
         ( _bbmin[2] > _bbmax[2] )   ) {
279
280
      
      // Invalid bounding box, try to recover
281
      setScenePos( properties_.sceneCenter() , properties_.sceneRadius(), _resetTrackBall );
282
283
    
      // Update bounding box to match the scene geometry after recovery
Jan Möbius's avatar
Jan Möbius committed
284
285
      _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
286
287
    } else {
      
288
      // For very small scenes, we set the scene radius to 0.1
Jan Möbius's avatar
Jan Möbius committed
289
      // otherwise we take the real radius
Jan Möbius's avatar
Jan Möbius committed
290
291
      if ( ( _bbmax - _bbmin ).max() < OpenFlipperSettings().value("Core/Gui/glViewer/minimalSceneSize",0.1).toDouble() )  {
        setScenePos( ( _bbmin + _bbmax )        * 0.5,
292
                     OpenFlipperSettings().value("Core/Gui/glViewer/minimalSceneSize",0.1).toDouble(),
Jan Möbius's avatar
Jan Möbius committed
293
294
295
                     _resetTrackBall);
                   
      } else {
Jan Möbius's avatar
Jan Möbius committed
296
297
        setScenePos( ( _bbmin + _bbmax )        * 0.5,
                     ( _bbmax - _bbmin ).norm() * 0.5,
Jan Möbius's avatar
Jan Möbius committed
298
299
300
301
                     _resetTrackBall); 
      }
                   
    }
302
303
                   
    // remember the new bounding box for the state
Jan Möbius's avatar
Jan Möbius committed
304
    glstate_->set_bounding_box(_bbmin,_bbmax);
305
    
Jan Möbius's avatar
 
Jan Möbius committed
306
  }
307
  
Jan Möbius's avatar
 
Jan Möbius committed
308
309
310
311
312
313
314
315
316
317

  updateGL();

  emit(signalSceneGraphChanged(sceneGraphRoot_));
}


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


Jan Möbius's avatar
   
Jan Möbius committed
318
void glViewer::trackMouse(bool _track)
Jan Möbius's avatar
 
Jan Möbius committed
319
320
321
322
323
324
325
{
  trackMouse_ = _track;
}


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

326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
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
346
void glViewer::perspectiveProjection()
Jan Möbius's avatar
 
Jan Möbius committed
347
348
349
350
351
352
{
  projectionMode(PERSPECTIVE_PROJECTION);
  updateGL();
}


Jan Möbius's avatar
   
Jan Möbius committed
353
void glViewer::orthographicProjection()
Jan Möbius's avatar
 
Jan Möbius committed
354
355
356
357
358
359
{
  projectionMode(ORTHOGRAPHIC_PROJECTION);
  updateGL();
}


Jan Möbius's avatar
   
Jan Möbius committed
360
void glViewer::toggleProjectionMode()
Jan Möbius's avatar
 
Jan Möbius committed
361
362
363
364
365
366
367
368
369
370
{
  if (projectionMode_ == ORTHOGRAPHIC_PROJECTION)
    projectionMode(PERSPECTIVE_PROJECTION);
  else
    projectionMode(ORTHOGRAPHIC_PROJECTION);

  updateGL();
}


Jan Möbius's avatar
   
Jan Möbius committed
371
void glViewer::projectionMode(ProjectionMode _p)
Jan Möbius's avatar
 
Jan Möbius committed
372
373
{
  if ((projectionMode_ = _p) == ORTHOGRAPHIC_PROJECTION)
374
    emit projectionModeChanged( true );
Jan Möbius's avatar
 
Jan Möbius committed
375
  else
376
    emit projectionModeChanged( false );
Jan Möbius's avatar
 
Jan Möbius committed
377
378

  updateProjectionMatrix();
379

380
381
  setCoordSysProjection(_p);

382
  emit viewChanged();
Jan Möbius's avatar
 
Jan Möbius committed
383
384
}

385
386
387
void glViewer::toggleNavigationMode()
{
  if (navigationMode_ == NORMAL_NAVIGATION)
Mike Kremer's avatar
Mike Kremer committed
388
    navigationMode(FIRSTPERSON_NAVIGATION);
389
390
391
392
393
394
395
396
397
398
399
400
401
  else
    navigationMode(NORMAL_NAVIGATION);
}


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

402
403
404
405
406
407
408
409
410
411
412
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();
}

Jan Möbius's avatar
   
Jan Möbius committed
413
void glViewer::updateProjectionMatrix()
Jan Möbius's avatar
 
Jan Möbius committed
414
415
416
417
418
419
420
421
{
  if( projectionUpdateLocked_ )
    return;

  makeCurrent();

  glstate_->reset_projection();

422
  const double aspect = this->aspect_ratio();
423
  // In stereo mode we have to use a perspective matrix
424
  if ( projectionMode_ == PERSPECTIVE_PROJECTION)
Jan Möbius's avatar
 
Jan Möbius committed
425
  {
426

427
    // Get fovy
428
    const double fovy = this->field_of_view_vertical();
429
430

    glstate_->perspective(fovy, (GLdouble) aspect,
431
                          near_plane(), far_plane());
Jan Möbius's avatar
Jan Möbius committed
432
433
434
  }
  else
  {
Jan Möbius's avatar
 
Jan Möbius committed
435

436
437
438
    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
439
  }
440

Jan Möbius's avatar
 
Jan Möbius committed
441
442
443
444
445
446
}


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


447
void glViewer::setScenePos(const ACG::Vec3d& _center, double _radius, const bool _resetTrackBall)
Jan Möbius's avatar
 
Jan Möbius committed
448
{
449
  if(_resetTrackBall) {
450
    properties_.trackballCenter(_center);
451
452
  }

453
  properties_.sceneCenter(_center);
454

455
456
  properties_.sceneRadius(_radius);
  properties_.trackballRadius(_radius);
457

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

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

   // Safety check, if near < 0
Jan Möbius's avatar
Jan Möbius committed
464
   if ( nearPlane <= 0.0 ) {
465
     std::cerr << "Error in BaseViewer drawScene, nearplane <= 0.0" << std::endl;
Jan Möbius's avatar
Jan Möbius committed
466
     nearPlane = 0.000000000000001;
467
468
469
   }

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

Jan Möbius's avatar
Jan Möbius committed
475
  properties_.setPlanes(nearPlane,farPlane);
476
  properties_.orthoWidth(_radius);
Jan Möbius's avatar
 
Jan Möbius committed
477

478
479
480
481
  updateProjectionMatrix();
  updateGL();

  emit viewChanged();
482
483
484
485
486
487
}


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


Jan Möbius's avatar
   
Jan Möbius committed
488
void glViewer::viewingDirection( const ACG::Vec3d& _dir, const ACG::Vec3d& _up )
Jan Möbius's avatar
 
Jan Möbius committed
489
490
{
  // calc eye point for this direction
491
  ACG::Vec3d eye = properties_.sceneCenter() - _dir * ( 3.0 * properties_.sceneRadius());
Jan Möbius's avatar
 
Jan Möbius committed
492
493

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

496
  emit viewChanged();
Jan Möbius's avatar
 
Jan Möbius committed
497
498
}

499
500
501
502
503
504
505
//-----------------------------------------------------------------------------

void glViewer::lookAt(const ACG::Vec3d& _eye, const ACG::Vec3d& _center, const ACG::Vec3d& _up) {
    
    glstate_->reset_modelview();
    glstate_->lookAt(_eye, _center, _up);
    
506
507
    properties_.sceneCenter( _center );
    properties_.sceneRadius( (properties_.sceneCenter() - _eye).norm() );
508
509
510
    
    emit viewChanged();
}
Jan Möbius's avatar
 
Jan Möbius committed
511
512
513

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

Jan Möbius's avatar
   
Jan Möbius committed
514
void glViewer::normalsMode(NormalsMode _mode)
Jan Möbius's avatar
 
Jan Möbius committed
515
516
517
518
519
520
{
  makeCurrent();

  switch(normalsMode_ = _mode)
  {
    case DONT_TOUCH_NORMALS:
521
      ACG::GLState::disable(GL_NORMALIZE);
Jan Möbius's avatar
 
Jan Möbius committed
522
523
524
      break;

    case NORMALIZE_NORMALS:
525
      ACG::GLState::enable(GL_NORMALIZE);
Jan Möbius's avatar
 
Jan Möbius committed
526
527
528
529
530
531
532
533
534
535
536
      break;
  }

  updateGL();
}


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


void
Jan Möbius's avatar
   
Jan Möbius committed
537
glViewer::copyToImage( QImage& _image,
Jan Möbius's avatar
Jan Möbius committed
538
539
		       unsigned int _l, unsigned int _t,
		       unsigned int _w, unsigned int _h,
540
			     GLenum /* _buffer */ )
Jan Möbius's avatar
 
Jan Möbius committed
541
{
542
543
544

//    makeCurrent();

Jan Möbius's avatar
Jan Möbius committed
545
  _image = glWidget_->grabFrameBuffer(true).copy (_l, _t, _w, _h).convertToFormat (QImage::Format_RGB32);
Jan Möbius's avatar
 
Jan Möbius committed
546
547
548
549
550
551
}


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


Jan Möbius's avatar
   
Jan Möbius committed
552
void glViewer::updateGL()
Jan Möbius's avatar
 
Jan Möbius committed
553
{
Jan Möbius's avatar
   
Jan Möbius committed
554
  if (!properties_.updateLocked() && isVisible() )
Jan Möbius's avatar
 
Jan Möbius committed
555
  {
Jan Möbius's avatar
Jan Möbius committed
556
    updatePickCache_ = true;
Jan Möbius's avatar
   
Jan Möbius committed
557
    update();
558
559

    emit viewUpdated();
Jan Möbius's avatar
 
Jan Möbius committed
560
561
562
563
564
565
566
567
  }
}



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


Jan Möbius's avatar
   
Jan Möbius committed
568
void glViewer::drawScene()
Jan Möbius's avatar
 
Jan Möbius committed
569
{
570
571
572
573
  
  // Inside the glWidget rendering, the system should not send extra updates
  properties_.blockSignals(true);
  
Jan Möbius's avatar
 
Jan Möbius committed
574
575
576
  QTime  timer;
  timer.start();

Jan Möbius's avatar
   
Jan Möbius committed
577
578
579
580
  // *****************************************************************
  // Adjust clipping planes
  // *****************************************************************
  // Far plane
581
  ACG::Vec3d c = glstate_->modelview().transform_point(properties_.sceneCenter());
Jan Möbius's avatar
   
Jan Möbius committed
582

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

  // Safety check, if near < 0
Jan Möbius's avatar
Jan Möbius committed
587
  if ( nearPlane <= 0.0 ) {
588
    std::cerr << "Error in BaseViewer drawScene, nearplane < 0" << std::endl;
Jan Möbius's avatar
Jan Möbius committed
589
    nearPlane = 0.000000000000001;
590
591
592
  }

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

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

Jan Möbius's avatar
 
Jan Möbius committed
600
601
602
603
604
605
  updateProjectionMatrix();

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

  makeCurrent();
606

Jan Möbius's avatar
Jan Möbius committed
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
  // 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 {
//
//  }

628
629
630
631
632
633
634
635
636
637
  // Clear back buffer here:
  // Render plugins do not have to worry about using scissor test for clearing their viewports later on.
  glClearColor(properties_.backgroundColor()[0], properties_.backgroundColor()[1], properties_.backgroundColor()[2], 1.0f);
  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
638

639
  // Check if we use build in default renderer
Jan Möbius's avatar
Jan Möbius committed
640
  if ( renderManager().activeId( properties_.viewerId() ) == 0 ) {
641
    drawScene_mono();
Jan Möbius's avatar
Jan Möbius committed
642
  } else {
643
644
645
646
647
648
649
650
651
    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() );

    renderPlugin->render(glstate_,properties_);
Jan Möbius's avatar
Jan Möbius committed
652
  }
653
  checkGLError();
Jan Möbius's avatar
Jan Möbius committed
654
655


656
657
  // =================================================================================
  // Post-Processing pipeline
Jan Möbius's avatar
Jan Möbius committed
658
659


660
  const int numPostProcessors = postProcessorManager().numActive(properties_.viewerId());
Jan Möbius's avatar
Jan Möbius committed
661

662
663
664
665
  if (numPostProcessors)
  {
    GLuint backbufferFbo = 0;
    glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, (GLint*)&backbufferFbo);
Jan Möbius's avatar
Jan Möbius committed
666
667


668
    updatePostProcessingBufs(glstate_->viewport_width(),glstate_->viewport_height());
Jan Möbius's avatar
Jan Möbius committed
669

670
    readBackBuffer(glstate_);
Jan Möbius's avatar
Jan Möbius committed
671

672
673
674
    // 1st post processing source: active fbo
    int postProcSrc = 1;
    PostProcessorInput postProcInput;
Jan Möbius's avatar
Jan Möbius committed
675

676
677
678
679
    postProcInput.colorTex_ = readBackFbo_.getAttachment(GL_COLOR_ATTACHMENT0);
    postProcInput.depthTex_ = readBackFbo_.getAttachment(GL_DEPTH_ATTACHMENT);
    postProcInput.width     = readBackFbo_.width();
    postProcInput.height    = readBackFbo_.height();
Jan Möbius's avatar
Jan Möbius committed
680

681
682
    // execute post processing chain with 2 FBOs
    for (int i = 0; i < numPostProcessors; ++i)  {
Jan Möbius's avatar
Jan Möbius committed
683

684
      int postProcTarget = 1 - postProcSrc;
Jan Möbius's avatar
Jan Möbius committed
685

686
      GLuint targetFBO = postProcessFBO_[postProcTarget].getFboID();
Jan Möbius's avatar
Jan Möbius committed
687

688
689
690
      // write to back buffer in last step
      if (i + 1 == numPostProcessors)
        targetFBO = backbufferFbo;
Jan Möbius's avatar
Jan Möbius committed
691

692
693
694
695
      // apply post processor
      PostProcessorInfo* proc = postProcessorManager().active( properties_.viewerId(), i );
      if (proc && proc->plugin)
        proc->plugin->postProcess(glstate_, postProcInput, targetFBO);
Jan Möbius's avatar
Jan Möbius committed
696
697


698
699
      // swap target/source fbo
      postProcSrc = postProcTarget;
Jan Möbius's avatar
Jan Möbius committed
700

701
702
      postProcInput.colorTex_ = postProcessFBO_[postProcSrc].getAttachment(GL_COLOR_ATTACHMENT0);
    }
703
  }
704
  
Jan Möbius's avatar
Jan Möbius committed
705
706
707
708
709
710

  // =================================================================================

  // unbind vbo for qt log window
  glBindBuffer(GL_ARRAY_BUFFER, 0);

711
712
713
  glActiveTexture(GL_TEXTURE0);
  glBindTexture(GL_TEXTURE_2D, 0);

Jan Möbius's avatar
Jan Möbius committed
714
715
716
717
718
719
720
721
722
723
//  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
724
  glFinish();
Jan Möbius's avatar
Jan Möbius committed
725

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

728
729
730
  
  // Inside the glWidget rendering, the system should not send extra updates
  properties_.blockSignals(false);
Jan Möbius's avatar
Jan Möbius committed
731

Jan Möbius's avatar
 
Jan Möbius committed
732
733
734
735
736
737
}


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


Jan Möbius's avatar
   
Jan Möbius committed
738
void glViewer::drawScene_mono()
Jan Möbius's avatar
 
Jan Möbius committed
739
{
740
741
742
743
  if (sceneGraphRoot_) {
    ViewObjectMarker *oM = properties_.objectMarker();
    GLuint refBits = 0;
    QSet<GLuint> references;
744

745
746
747
    if (oM)
    {
      glClear (GL_STENCIL_BUFFER_BIT);
748
      ACG::GLState::enable (GL_STENCIL_TEST);
749
750
      glStencilOp (GL_KEEP, GL_KEEP, GL_ZERO);
      glStencilFunc (GL_ALWAYS, 0, ~0);
751

752
753
      for (PluginFunctions::ObjectIterator o_it(PluginFunctions::ALL_OBJECTS, DATA_ALL) ;
          o_it != PluginFunctions::objectsEnd(); ++o_it)
754
      {
755
756
757
758
        bool ok;
        GLuint ref;

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

760
        if (ok)
761
        {
762
763
764
765
          o_it->stencilRefNode ()->setReference (ref);
          o_it->stencilRefNode ()->show ();
          refBits |= ref;
          references << ref;
766
        }
767
768
        else
          o_it->stencilRefNode ()->hide ();
769
      }
770
771
    }

Jan Möbius's avatar
Jan Möbius committed
772
773
774
    // First pass
    ACG::SceneGraph::DrawAction pass1( properties_.drawMode(), *glstate_ , false);
    ACG::SceneGraph::traverse_multipass(sceneGraphRoot_, pass1, *glstate_, properties_.drawMode() );
775

Jan Möbius's avatar
Jan Möbius committed
776
777
778
    // 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
779

780
781
782
    if (oM)
    {
      if (oM->type() == ViewObjectMarker::PerBit)
Jan Möbius's avatar
 
Jan Möbius committed
783
      {
784
785
786
787
        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
788
      }
789

790
      glPushAttrib(GL_ALL_ATTRIB_BITS);
791

792
      ACG::GLState::enable(GL_BLEND);
793
794
795
      ACG::GLState::disable(GL_DEPTH_TEST);
      ACG::GLState::disable(GL_LIGHTING);
      ACG::GLState::disable(GL_DITHER);
796

797
798
      int vp_l, vp_b, vp_w, vp_h;
      glstate_->get_viewport (vp_l, vp_b, vp_w, vp_h);
799

800
801
802
803
804
805
806
      glMatrixMode(GL_PROJECTION);
      glPushMatrix ();
      glLoadIdentity();
      glOrtho(0, vp_w, vp_h, 0, 0, 1.0);
      glMatrixMode(GL_MODELVIEW);
      glPushMatrix ();
      glLoadIdentity();
807

808
      glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
809

810
811
812
813
814
815
816
      foreach (unsigned int ref, references)
      {
        bool ok;
        GLenum sfactor;
        GLenum dfactor;
        ACG::Vec4f color;
        unsigned int mask = ~0;
817

818
        if (oM->type() == ViewObjectMarker::PerBit)
819
        {
820
821
          ok = oM->blendForStencilRefBit (ref, sfactor, dfactor, color);
          mask = ref;
822
        }
823
824
        else
          ok = oM->blendForStencilRefNumber (ref, sfactor, dfactor, color);
825

826
827
        if (!ok)
          continue;
828

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

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

834
835
836
837
838
839
840
841
        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
842

843
844
845
846
      glMatrixMode(GL_PROJECTION);
      glPopMatrix ();
      glMatrixMode(GL_MODELVIEW);
      glPopMatrix ();
Jan Möbius's avatar
 
Jan Möbius committed
847

848
      glPopAttrib ();
849
      ACG::GLState::disable (GL_STENCIL_TEST);
Jan Möbius's avatar
 
Jan Möbius committed
850
    }
851
852


Jan Möbius's avatar
 
Jan Möbius committed
853
  }
Jan Möbius's avatar
Jan Möbius committed
854

855
  if (properties_.cursorPainter() && properties_.cursorPainter()->enabled () && properties_.cursorPositionValid() )
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
856
857
858
859
860
  {
    glstate_->push_modelview_matrix ();
    // reset view transformation
    glstate_->reset_modelview ();
    // translate cursor position to 0,0
861
    glstate_->translate ( properties_.cursorPoint3D() );
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
862
    // paint cursor
863
    properties_.cursorPainter()->paintCursor (glstate_);
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
864
865
    glstate_->pop_modelview_matrix ();
  }
866

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

Jan Möbius's avatar
   
Jan Möbius committed
869
void glViewer::setHome()
Jan Möbius's avatar
 
Jan Möbius committed
870
871
872
{
  home_modelview_          = glstate_->modelview();
  home_inverse_modelview_  = glstate_->inverse_modelview();
873
  homeOrthoWidth_          = properties_.orthoWidth();
874
875
  home_center_             = properties_.trackballCenter();
  home_radius_             = properties_.trackballRadius();
Jan Möbius's avatar
 
Jan Möbius committed
876
877
878
}


Jan Möbius's avatar
   
Jan Möbius committed
879
void glViewer::home()
Jan Möbius's avatar
 
Jan Möbius committed
880
881
882
{
  makeCurrent();
  glstate_->set_modelview(home_modelview_, home_inverse_modelview_);
883
  properties_.orthoWidth( homeOrthoWidth_ );
884
885
  properties_.trackballCenter( home_center_ );
  properties_.trackballRadius(home_radius_);
Jan Möbius's avatar
 
Jan Möbius committed
886
887
  updateProjectionMatrix();
  updateGL();
888

889
  emit viewChanged();
Jan Möbius's avatar
 
Jan Möbius committed
890
891
892
893
894

}

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

Jan Möbius's avatar
   
Jan Möbius committed
895
void glViewer::viewAll()
Jan Möbius's avatar
 
Jan Möbius committed
896
{
897
  makeCurrent();
Jan Möbius's avatar
 
Jan Möbius committed
898

899
900
  // 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
901

902
903
904
  // 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()));
905

906
907
908
909
  properties_.orthoWidth( 1.1 * properties_.sceneRadius() );
  double aspect = (double) glWidth() / (double) glHeight();
  if (aspect > 1.0)
    properties_.orthoWidth( aspect * properties_.orthoWidth() ) ;
910

Jan Möbius's avatar
Jan Möbius committed
911
912
913
914
915
  unsigned int maxPases = 1;
  ACG::Vec3d bbmin,bbmax;
  ACG::SceneGraph::analyzeSceneGraph(PluginFunctions::getSceneGraphRootNode(),maxPases,bbmin,bbmax);

  sceneGraph ( PluginFunctions::getSceneGraphRootNode(), maxPases,bbmin,bbmax,true);
916

917
918
919
  properties_.unLockUpdate();
  updateProjectionMatrix();
  updateGL();
920

921
  emit viewChanged();
Jan Möbius's avatar
 
Jan Möbius committed
922
923
924
925
926
927
928

}


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


Jan Möbius's avatar
   
Jan Möbius committed
929
void glViewer::setView(const ACG::GLMatrixd& _modelview,
Jan Möbius's avatar
 
Jan Möbius committed
930
931
932
933
934
			                  const ACG::GLMatrixd& _inverse_modelview)
{
  makeCurrent();
  glstate_->set_modelview(_modelview, _inverse_modelview);
  updateGL();
935

936
  emit viewChanged();
Jan Möbius's avatar
 
Jan Möbius committed
937
938
939
940
941
942
}


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


Jan Möbius's avatar
   
Jan Möbius committed
943
void glViewer::initializeGL()
Jan Möbius's avatar
 
Jan Möbius committed
944
945
946
{

  // lock update
947
  properties_.lockUpdate();
Jan Möbius's avatar
 
Jan Möbius committed
948
949
950
951
952

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

  // OpenGL state
953
954
  ACG::GLState::enable(GL_DEPTH_TEST);
  ACG::GLState::enable(GL_LIGHTING);
955
  ACG::GLState::disable(GL_DITHER);
956
  ACG::GLState::shadeModel( GL_FLAT );
Jan Möbius's avatar
 
Jan Möbius committed
957
958
959
960
961


  projectionMode(   projectionMode_   );
  normalsMode(      normalsMode_      );

962
  // Update all settings which would require a redraw
963
  applyProperties();
Jan Möbius's avatar
 
Jan Möbius committed
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981

  // 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)
982
  properties_.unLockUpdate();
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
983

984
985
986
987
  initialized_ = true;

  if (sceneGraphRoot_)
  {
Jan Möbius's avatar
Jan Möbius committed
988
989
990
991
992
993
994
    unsigned int maxPases = 1;
    ACG::Vec3d bbmin,bbmax;
    ACG::SceneGraph::analyzeSceneGraph(sceneGraphRoot_,maxPases,bbmin,bbmax);

    sceneGraph ( sceneGraphRoot_, maxPases,bbmin,bbmax,true);

    viewAll();
995
  }
Jan Möbius's avatar
 
Jan Möbius committed
996
997
998
999
1000
1001
}


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


Jan Möbius's avatar
   
Jan Möbius committed
1002
void glViewer::paintGL()
Jan Möbius's avatar
 
Jan Möbius committed
1003
{
1004
1005
  if (!initialized_)
    initializeGL ();
Jan Möbius's avatar
 
Jan Möbius committed
1006

1007
  if (!properties_.updateLocked())
Jan Möbius's avatar
 
Jan Möbius committed
1008
  {
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
1009
1010
    ACG::Vec4f clear_color;

1011
    properties_.lockUpdate();
Jan Möbius's avatar
 
Jan Möbius committed
1012
1013
1014

    glPushAttrib (GL_ALL_ATTRIB_BITS);

1015
1016
    ACG::GLState::enable(GL_DEPTH_TEST);
    ACG::GLState::enable(GL_LIGHTING);
1017
    ACG::GLState::disable(GL_DITHER);
1018
    ACG::GLState::shadeModel( GL_FLAT );
Jan Möbius's avatar
 
Jan Möbius committed
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028

    glMatrixMode(GL_PROJECTION);
    glPushMatrix();

    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();


    normalsMode(      normalsMode_      );

1029
    applyProperties();
1030

1031
    glstate_->setState();
Jan Möbius's avatar
 
Jan Möbius committed
1032
1033
1034

    glColor4f(1.0,0.0,0.0,1.0);

1035
    glstate_->clearBuffers ();
Jan Möbius's avatar
 
Jan Möbius committed
1036

1037
    properties_.unLockUpdate();
Jan Möbius's avatar
 
Jan Möbius committed
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048

    // draw scene
    drawScene();

    glPopMatrix();

    glMatrixMode(GL_PROJECTION);
    glPopMatrix();

    glPopAttrib ();
  }
1049

Jan Möbius's avatar
 
Jan Möbius committed
1050
1051
1052
1053
1054
1055
}


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


Jan Möbius's avatar
   
Jan Möbius committed
1056
void glViewer::resizeEvent(QGraphicsSceneResizeEvent *)
Jan Möbius's avatar
 
Jan Möbius committed
1057
1058
{
  updateProjectionMatrix();
Jan Möbius's avatar
   
Jan Möbius committed
1059
  glstate_->viewport(scenePos().x(),
Jan Möbius's avatar
Jan Möbius committed
1060
1061
1062
                     scene()->height () - scenePos().y() - size().height (),
                     size().width (), size().height (),
                     scene()->width (), scene()->height ());
Jan Möbius's avatar
   
Jan Möbius committed
1063
  update();
1064

1065
  emit viewChanged();
Jan Möbius's avatar
 
Jan Möbius committed
1066
1067
}

Jan Möbius's avatar
   
Jan Möbius committed
1068
1069
1070
void glViewer::moveEvent (QGraphicsSceneMoveEvent *)
{
  glstate_->viewport(scenePos().x(),
Jan Möbius's avatar
Jan Möbius committed
1071
1072
1073
                     scene()->height () - scenePos().y() - size().height (),
                     size().width (), size().height (),
                     scene()->width (), scene()->height ());
Jan Möbius's avatar
   
Jan Möbius committed
1074
  update();
1075

1076
  emit viewChanged();
Jan Möbius's avatar
   
Jan Möbius committed
1077
}
Jan Möbius's avatar
 
Jan Möbius committed
1078
1079
1080

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

1081
void glViewer::encodeView(QString& _view, const QSize& _windowSize /*= QSize()*/, const int _splitterWidth /*=-1*/)
Jan Möbius's avatar
 
Jan Möbius committed
1082
{
1083
  // Get current matrices
Jan Möbius's avatar
 
Jan Möbius committed
1084
1085
1086
  const ACG::GLMatrixd m = glstate_->modelview();
  const ACG::GLMatrixd p = glstate_->projection();

1087
  // Add modelview matrix to output
1088
  _view += QString(COPY_PASTE_VIEW_START_STRING) + "\n";
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
  _view += QString::number(m(0,0)) + " " + QString::number(m(0,1)) + " " + QString::number(m(0,2)) + " " + QString::number(m(0,3)) + "\n";
  _view += QString::number(m(1,0)) + " " + QString::number(m(1,1)) + " " + QString::number(m(1,2)) + " " + QString::number(m(1,3)) + "\n";
  _view += QString::number(m(2,0)) + " " + QString::number(m(2,1)) + " " + QString::number(m(2,2)) + " " + QString::number(m(2,3)) + "\n";
  _view += QString::number(m(3,0)) + " " + QString::number(m(3,1)) + " " + QString::number(m(3,2)) + " " + QString::number(m(3,3)) + "\n";