QtBaseViewer.cc 65.6 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-2011 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 64 65 66 67 68 69 70 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
#include <ACG/GL/gl.hh>

#include <iostream>
#include <string>
#include <assert.h>

#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>

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

109 110
#include <QImageWriter>

Jan Möbius's avatar
 
Jan Möbius committed
111 112 113 114 115 116 117 118
#ifdef max
#  undef max
#endif

#ifdef min
#  undef min
#endif

119
#include <OpenFlipper/BasePlugin/PluginFunctions.hh>
Jan Möbius's avatar
Jan Möbius committed
120
#include <OpenFlipper/common/ViewObjectMarker.hh>
Jan Möbius's avatar
 
Jan Möbius committed
121

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

124 125
#include <QGLFramebufferObject>

126
#include <OpenFlipper/common/RendererInfo.hh>
127 128
#include <OpenFlipper/BasePlugin/PostProcessorInterface.hh>

Jan Möbius's avatar
 
Jan Möbius committed
129 130 131 132 133 134
//== NAMESPACES ===============================================================



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

135
static const char          COPY_PASTE_VIEW_START_STRING[] =
Jan Möbius's avatar
 
Jan Möbius committed
136 137 138 139 140
  "ACG::QtWidgets::QGLViewerWidget encoded view";

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


141
glViewer::glViewer( QGraphicsScene* _scene,
142
                    QGLWidget* _glWidget,
143
                    Viewer::ViewerProperties& _properties,
144
                    QGraphicsWidget* _parent) :
Jan Möbius's avatar
 
Jan Möbius committed
145
  QGraphicsWidget(_parent),
Jan Möbius's avatar
 
Jan Möbius committed
146 147
  glareaGrabbed_(false),
  projectionUpdateLocked_(false),
Jan Möbius's avatar
 
Jan Möbius committed
148 149
  glScene_(_scene),
  glWidget_(_glWidget),
Jan Möbius's avatar
Jan Möbius committed
150 151 152
  pickCache_(0),
  updatePickCache_(true),
  pickCacheSupported_(true),
153
  clickEvent_(QEvent::MouseButtonPress, QPoint (), Qt::NoButton, Qt::NoButton, Qt::NoModifier),
Dirk Wilden's avatar
Dirk Wilden committed
154
  properties_(_properties),
155
  glstate_(0),
Jan Möbius's avatar
Jan Möbius committed
156 157 158 159 160 161
  initialized_(false),
  flyAnimationPerspective_(0),
  flyAnimationOrthogonal_(0),
  flyAngle_(0.0),
  currentAnimationPos_(0.0),
  flyMoveBack_(false)
Jan Möbius's avatar
 
Jan Möbius committed
162 163 164
{

  // widget stuff
165
  createWidgets();
Jan Möbius's avatar
 
Jan Möbius committed
166 167 168

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

Jan Möbius's avatar
 
Jan Möbius committed
171 172
  // state
  isRotating_       = false;
Mike Kremer's avatar
Mike Kremer committed
173
  lookAround_       = false;
Jan Möbius's avatar
 
Jan Möbius committed
174 175 176

  sceneGraphRoot_   = 0;

177
  normalsMode_      = NORMALIZE_NORMALS;
Jan Möbius's avatar
 
Jan Möbius committed
178
  projectionMode_   = PERSPECTIVE_PROJECTION;
Jan Möbius's avatar
Jan Möbius committed
179
  navigationMode_   = NORMAL_NAVIGATION;
180

Jan Möbius's avatar
 
Jan Möbius committed
181 182 183 184 185 186 187 188 189 190 191 192 193 194
  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 ();

195 196 197 198
  // timer for animation
  timer_ = new QTimer( this );
  connect( timer_, SIGNAL(timeout()), this, SLOT( slotAnimation()) );

199 200
  fovyModifier_ = 1.0;

201 202 203
  allowRotation_ = true;


Jan Möbius's avatar
 
Jan Möbius committed
204 205 206
  connect( &properties_,SIGNAL(updated()), this, SLOT( slotPropertiesUpdated() ) );


Dirk Wilden's avatar
Dirk Wilden committed
207 208 209
  //check for updated properties once
  slotPropertiesUpdated();

Jan Möbius's avatar
 
Jan Möbius committed
210
  setAcceptDrops(true);
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
211

212
  setHome();
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
213

214 215
  clickTimer_.setSingleShot (true);
  connect (&clickTimer_, SIGNAL(timeout ()), this, SLOT(slotClickTimeout ()));
Jan Möbius's avatar
 
Jan Möbius committed
216 217 218 219 220 221
}


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


Jan Möbius's avatar
 
Jan Möbius committed
222
glViewer::~glViewer()
Jan Möbius's avatar
 
Jan Möbius committed
223 224 225 226 227 228 229 230
{
  delete glstate_;
}


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


231 232 233 234 235
//QSizeF
//glViewer::sizeHint(Qt::SizeHint which, const QSizeF & constraint) const
//{
//  return QSizeF( 600, 600 );
//}
Jan Möbius's avatar
 
Jan Möbius committed
236 237 238 239

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


Jan Möbius's avatar
 
Jan Möbius committed
240
void glViewer::makeCurrent() {
Jan Möbius's avatar
 
Jan Möbius committed
241 242 243
  glWidget_->makeCurrent();
}

Jan Möbius's avatar
 
Jan Möbius committed
244
void glViewer::swapBuffers() {
Jan Möbius's avatar
 
Jan Möbius committed
245 246 247 248 249 250
  glWidget_->swapBuffers();
}


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

Jan Möbius's avatar
Jan Möbius committed
251 252 253 254 255
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
256 257 258
{
  sceneGraphRoot_ = _root;

Jan Möbius's avatar
Jan Möbius committed
259
  if (sceneGraphRoot_ )
Jan Möbius's avatar
 
Jan Möbius committed
260 261
  {

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

  updateGL();

  emit(signalSceneGraphChanged(sceneGraphRoot_));
}


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


Jan Möbius's avatar
 
Jan Möbius committed
307
void glViewer::trackMouse(bool _track)
Jan Möbius's avatar
 
Jan Möbius committed
308 309 310 311 312 313 314
{
  trackMouse_ = _track;
}


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

315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334
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
335
void glViewer::perspectiveProjection()
Jan Möbius's avatar
 
Jan Möbius committed
336 337 338 339 340 341
{
  projectionMode(PERSPECTIVE_PROJECTION);
  updateGL();
}


Jan Möbius's avatar
 
Jan Möbius committed
342
void glViewer::orthographicProjection()
Jan Möbius's avatar
 
Jan Möbius committed
343 344 345 346 347 348
{
  projectionMode(ORTHOGRAPHIC_PROJECTION);
  updateGL();
}


Jan Möbius's avatar
 
Jan Möbius committed
349
void glViewer::toggleProjectionMode()
Jan Möbius's avatar
 
Jan Möbius committed
350 351 352 353 354 355 356 357 358 359
{
  if (projectionMode_ == ORTHOGRAPHIC_PROJECTION)
    projectionMode(PERSPECTIVE_PROJECTION);
  else
    projectionMode(ORTHOGRAPHIC_PROJECTION);

  updateGL();
}


Jan Möbius's avatar
 
Jan Möbius committed
360
void glViewer::projectionMode(ProjectionMode _p)
Jan Möbius's avatar
 
Jan Möbius committed
361 362
{
  if ((projectionMode_ = _p) == ORTHOGRAPHIC_PROJECTION)
363
    emit projectionModeChanged( true );
Jan Möbius's avatar
 
Jan Möbius committed
364
  else
365
    emit projectionModeChanged( false );
Jan Möbius's avatar
 
Jan Möbius committed
366 367

  updateProjectionMatrix();
368

369 370
  setCoordSysProjection(_p);

371
  emit viewChanged();
Jan Möbius's avatar
 
Jan Möbius committed
372 373
}

374 375 376
void glViewer::toggleNavigationMode()
{
  if (navigationMode_ == NORMAL_NAVIGATION)
Mike Kremer's avatar
Mike Kremer committed
377
    navigationMode(FIRSTPERSON_NAVIGATION);
378 379 380 381 382 383 384 385 386 387 388 389 390
  else
    navigationMode(NORMAL_NAVIGATION);
}


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

391 392 393 394 395 396 397 398 399 400 401
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
402

Jan Möbius's avatar
 
Jan Möbius committed
403
void glViewer::updateProjectionMatrix()
Jan Möbius's avatar
 
Jan Möbius committed
404 405 406 407 408 409 410 411
{
  if( projectionUpdateLocked_ )
    return;

  makeCurrent();

  glstate_->reset_projection();

412
  // In stereo mode we have to use a perspective matrix
413
  if ( projectionMode_ == PERSPECTIVE_PROJECTION)
Jan Möbius's avatar
 
Jan Möbius committed
414
  {
415 416 417 418 419 420 421
    double aspect;

    if (isVisible() && glWidth() && glHeight())
      aspect = (double) glWidth() / (double) glHeight();
    else
      aspect = 1.0;

422
    // Get fovy
423
    double fovy = OpenFlipperSettings().value("Core/Projection/FOVY", 45.0).toDouble() + fovyModifier_;
424 425

    glstate_->perspective(fovy, (GLdouble) aspect,
426
                          properties_.nearPlane(), properties_.farPlane());
Jan Möbius's avatar
Jan Möbius committed
427 428 429 430
  }
  else
  {
    double aspect;
Jan Möbius's avatar
Jan Möbius committed
431

432
    if (isVisible() && glWidth() && glHeight())
Jan Möbius's avatar
Jan Möbius committed
433 434
      aspect = (double) glWidth() / (double) glHeight();
    else
435
      aspect = 1.0;
Jan Möbius's avatar
 
Jan Möbius committed
436

437 438 439
    glstate_->ortho( -properties_.orthoWidth(), properties_.orthoWidth(),
                     -properties_.orthoWidth()/aspect, properties_.orthoWidth()/aspect,
                      properties_.nearPlane(), properties_.farPlane() );
Jan Möbius's avatar
 
Jan Möbius committed
440
  }
441

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


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


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

454
  properties_.sceneCenter(_center);
455

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

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

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

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

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

Jan Möbius's avatar
Jan Möbius committed
476
  properties_.setPlanes(nearPlane,farPlane);
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 628 629 630 631 632
  // 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 {
//
//  }


//  QGLFramebufferObject fbo( glstate_->viewport_width(),glstate_->viewport_height(),QGLFramebufferObject::CombinedDepthStencil );
//
//  fbo.bind();

633
  // Check if we use build in default renderer
Jan Möbius's avatar
Jan Möbius committed
634
  if ( renderManager().activeId( properties_.viewerId() ) == 0 ) {
635
    drawScene_mono();
Jan Möbius's avatar
Jan Möbius committed
636
  } else {
637
    renderManager().active( properties_.viewerId() )->plugin->render(glstate_,properties_);
Jan Möbius's avatar
Jan Möbius committed
638
  }
Jan Möbius's avatar
Jan Möbius committed
639 640


Jan Möbius's avatar
Jan Möbius committed
641 642
  if ( postProcessorManager().activeId( properties_.viewerId() ) != 0 ) {
    postProcessorManager().active( properties_.viewerId() )->plugin->postProcess(glstate_);
643
  }
644
  
Jan Möbius's avatar
Jan Möbius committed
645 646 647 648 649 650 651 652 653 654
//  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
655
  glFinish();
Jan Möbius's avatar
Jan Möbius committed
656

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

659 660 661
  
  // Inside the glWidget rendering, the system should not send extra updates
  properties_.blockSignals(false);
Jan Möbius's avatar
Jan Möbius committed
662

Jan Möbius's avatar
 
Jan Möbius committed
663 664 665 666 667 668
}


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


Jan Möbius's avatar
 
Jan Möbius committed
669
void glViewer::drawScene_mono()
Jan Möbius's avatar
 
Jan Möbius committed
670
{
671 672 673 674
  if (sceneGraphRoot_) {
    ViewObjectMarker *oM = properties_.objectMarker();
    GLuint refBits = 0;
    QSet<GLuint> references;
675

676 677 678
    if (oM)
    {
      glClear (GL_STENCIL_BUFFER_BIT);
679
      ACG::GLState::enable (GL_STENCIL_TEST);
680 681
      glStencilOp (GL_KEEP, GL_KEEP, GL_ZERO);
      glStencilFunc (GL_ALWAYS, 0, ~0);
682

683 684
      for (PluginFunctions::ObjectIterator o_it(PluginFunctions::ALL_OBJECTS, DATA_ALL) ;
          o_it != PluginFunctions::objectsEnd(); ++o_it)
685
      {
686 687 688 689
        bool ok;
        GLuint ref;

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

691
        if (ok)
692
        {
693 694 695 696
          o_it->stencilRefNode ()->setReference (ref);
          o_it->stencilRefNode ()->show ();
          refBits |= ref;
          references << ref;
697
        }
698 699
        else
          o_it->stencilRefNode ()->hide ();
700
      }
701 702
    }

Jan Möbius's avatar
Jan Möbius committed
703 704 705
    // First pass
    ACG::SceneGraph::DrawAction pass1( properties_.drawMode(), *glstate_ , false);
    ACG::SceneGraph::traverse_multipass(sceneGraphRoot_, pass1, *glstate_, properties_.drawMode() );
706

Jan Möbius's avatar
Jan Möbius committed
707 708 709
    // 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
710

711 712 713
    if (oM)
    {
      if (oM->type() == ViewObjectMarker::PerBit)
Jan Möbius's avatar
 
Jan Möbius committed
714
      {
715 716 717 718
        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
719
      }
720

721
      glPushAttrib(GL_ALL_ATTRIB_BITS);
722

723
      ACG::GLState::enable(GL_BLEND);
724 725 726
      ACG::GLState::disable(GL_DEPTH_TEST);
      ACG::GLState::disable(GL_LIGHTING);
      ACG::GLState::disable(GL_DITHER);
727

728 729
      int vp_l, vp_b, vp_w, vp_h;
      glstate_->get_viewport (vp_l, vp_b, vp_w, vp_h);
730

731 732 733 734 735 736 737
      glMatrixMode(GL_PROJECTION);
      glPushMatrix ();
      glLoadIdentity();
      glOrtho(0, vp_w, vp_h, 0, 0, 1.0);
      glMatrixMode(GL_MODELVIEW);
      glPushMatrix ();
      glLoadIdentity();
738

739
      glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
740

741 742 743 744 745 746 747
      foreach (unsigned int ref, references)
      {
        bool ok;
        GLenum sfactor;
        GLenum dfactor;
        ACG::Vec4f color;
        unsigned int mask = ~0;
748

749
        if (oM->type() == ViewObjectMarker::PerBit)
750
        {
751 752
          ok = oM->blendForStencilRefBit (ref, sfactor, dfactor, color);
          mask = ref;
753
        }
754 755
        else
          ok = oM->blendForStencilRefNumber (ref, sfactor, dfactor, color);
756

757 758
        if (!ok)
          continue;
759

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

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

765 766 767 768 769 770 771 772
        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
773

774 775 776 777
      glMatrixMode(GL_PROJECTION);
      glPopMatrix ();
      glMatrixMode(GL_MODELVIEW);
      glPopMatrix ();
Jan Möbius's avatar
 
Jan Möbius committed
778

779
      glPopAttrib ();
780
      ACG::GLState::disable (GL_STENCIL_TEST);
Jan Möbius's avatar
 
Jan Möbius committed
781
    }
782 783


Jan Möbius's avatar
 
Jan Möbius committed
784
  }
Jan Möbius's avatar
Jan Möbius committed
785

786
  if (properties_.cursorPainter() && properties_.cursorPainter()->enabled () && properties_.cursorPositionValid() )
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
787 788 789 790 791
  {
    glstate_->push_modelview_matrix ();
    // reset view transformation
    glstate_->reset_modelview ();
    // translate cursor position to 0,0
792
    glstate_->translate ( properties_.cursorPoint3D() );
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
793
    // paint cursor
794
    properties_.cursorPainter()->paintCursor (glstate_);
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
795 796
    glstate_->pop_modelview_matrix ();
  }
797

Jan Möbius's avatar
 
Jan Möbius committed
798 799
}

Jan Möbius's avatar
 
Jan Möbius committed
800
void glViewer::setHome()
Jan Möbius's avatar
 
Jan Möbius committed
801 802 803
{
  home_modelview_          = glstate_->modelview();
  home_inverse_modelview_  = glstate_->inverse_modelview();
804
  homeOrthoWidth_          = properties_.orthoWidth();
805 806
  home_center_             = properties_.trackballCenter();
  home_radius_             = properties_.trackballRadius();
Jan Möbius's avatar
 
Jan Möbius committed
807 808 809
}


Jan Möbius's avatar
 
Jan Möbius committed
810
void glViewer::home()
Jan Möbius's avatar
 
Jan Möbius committed
811 812 813
{
  makeCurrent();
  glstate_->set_modelview(home_modelview_, home_inverse_modelview_);
814
  properties_.orthoWidth( homeOrthoWidth_ );
815 816
  properties_.trackballCenter( home_center_ );
  properties_.trackballRadius(home_radius_);
Jan Möbius's avatar
 
Jan Möbius committed
817 818
  updateProjectionMatrix();
  updateGL();
819

820
  emit viewChanged();
Jan Möbius's avatar
 
Jan Möbius committed
821 822 823 824 825

}

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

Jan Möbius's avatar
 
Jan Möbius committed
826
void glViewer::viewAll()
Jan Möbius's avatar
 
Jan Möbius committed
827
{
828
  makeCurrent();
Jan Möbius's avatar
 
Jan Möbius committed
829

830 831
  // 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
832

833 834 835
  // 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()));
836

837 838 839 840
  properties_.orthoWidth( 1.1 * properties_.sceneRadius() );
  double aspect = (double) glWidth() / (double) glHeight();
  if (aspect > 1.0)
    properties_.orthoWidth( aspect * properties_.orthoWidth() ) ;
841

Jan Möbius's avatar
Jan Möbius committed
842 843 844 845 846
  unsigned int maxPases = 1;
  ACG::Vec3d bbmin,bbmax;
  ACG::SceneGraph::analyzeSceneGraph(PluginFunctions::getSceneGraphRootNode(),maxPases,bbmin,bbmax);

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

848 849 850
  properties_.unLockUpdate();
  updateProjectionMatrix();
  updateGL();
851

852
  emit viewChanged();
Jan Möbius's avatar
 
Jan Möbius committed
853 854 855 856 857 858 859

}


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


Jan Möbius's avatar
 
Jan Möbius committed
860
void glViewer::setView(const ACG::GLMatrixd& _modelview,
Jan Möbius's avatar
 
Jan Möbius committed
861 862 863 864 865
			                  const ACG::GLMatrixd& _inverse_modelview)
{
  makeCurrent();
  glstate_->set_modelview(_modelview, _inverse_modelview);
  updateGL();
866

867
  emit viewChanged();
Jan Möbius's avatar
 
Jan Möbius committed
868 869 870 871 872 873
}


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


Jan Möbius's avatar
 
Jan Möbius committed
874
void glViewer::initializeGL()
Jan Möbius's avatar
 
Jan Möbius committed
875 876 877
{

  // lock update
878
  properties_.lockUpdate();
Jan Möbius's avatar
 
Jan Möbius committed
879 880 881 882 883

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

  // OpenGL state
884 885
  ACG::GLState::enable(GL_DEPTH_TEST);
  ACG::GLState::enable(GL_LIGHTING);
886
  ACG::GLState::disable(GL_DITHER);
887
  ACG::GLState::shadeModel( GL_FLAT );
Jan Möbius's avatar
 
Jan Möbius committed
888 889 890 891 892


  projectionMode(   projectionMode_   );
  normalsMode(      normalsMode_      );

893
  // Update all settings which would require a redraw
894
  applyProperties();
Jan Möbius's avatar
 
Jan Möbius committed
895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912

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

915 916 917 918
  initialized_ = true;

  if (sceneGraphRoot_)
  {
Jan Möbius's avatar
Jan Möbius committed
919 920 921 922 923 924 925
    unsigned int maxPases = 1;
    ACG::Vec3d bbmin,bbmax;
    ACG::SceneGraph::analyzeSceneGraph(sceneGraphRoot_,maxPases,bbmin,bbmax);

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

    viewAll();
926
  }
Jan Möbius's avatar
 
Jan Möbius committed
927 928 929 930 931 932
}


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


Jan Möbius's avatar
 
Jan Möbius committed
933
void glViewer::paintGL()
Jan Möbius's avatar
 
Jan Möbius committed
934
{
935 936
  if (!initialized_)
    initializeGL ();
Jan Möbius's avatar
 
Jan Möbius committed
937

938
  if (!properties_.updateLocked())
Jan Möbius's avatar
 
Jan Möbius committed
939
  {
Jan Möbius's avatar
Dennis:  
Jan Möbius committed
940 941
    ACG::Vec4f clear_color;

942
    properties_.lockUpdate();
Jan Möbius's avatar
 
Jan Möbius committed
943 944 945

    glPushAttrib (GL_ALL_ATTRIB_BITS);

946 947
    ACG::GLState::enable(GL_DEPTH_TEST);
    ACG::GLState::enable(GL_LIGHTING);
948
    ACG::GLState::disable(GL_DITHER);
949
    ACG::GLState::shadeModel( GL_FLAT );
Jan Möbius's avatar
 
Jan Möbius committed
950 951 952 953 954 955 956 957 958 959

    glMatrixMode(GL_PROJECTION);
    glPushMatrix();

    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();


    normalsMode(      normalsMode_      );

960
    applyProperties();
961

962
    glstate_->setState();
Jan Möbius's avatar
 
Jan Möbius committed
963 964 965

    glColor4f(1.0,0.0,0.0,1.0);

966
    glstate_->clearBuffers ();
Jan Möbius's avatar
 
Jan Möbius committed
967

968
    properties_.unLockUpdate();
Jan Möbius's avatar
 
Jan Möbius committed
969 970 971 972 973 974 975 976 977 978 979

    // draw scene
    drawScene();

    glPopMatrix();

    glMatrixMode(GL_PROJECTION);
    glPopMatrix();

    glPopAttrib ();
  }
980

Jan Möbius's avatar
 
Jan Möbius committed
981 982 983 984 985 986
}


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


Jan Möbius's avatar
 
Jan Möbius committed
987
void glViewer::resizeEvent(QGraphicsSceneResizeEvent *)
Jan Möbius's avatar
 
Jan Möbius committed
988 989
{
  updateProjectionMatrix();
Jan Möbius's avatar
 
Jan Möbius committed
990
  glstate_->viewport(scenePos().x(),
Jan Möbius's avatar
Jan Möbius committed
991 992 993
                     scene()->height () - scenePos().y() - size().height (),
                     size().width (), size().height (),
                     scene()->width (), scene()->height ());
Jan Möbius's avatar
 
Jan Möbius committed
994
  update();
995

996
  emit viewChanged();
Jan Möbius's avatar
 
Jan Möbius committed
997 998
}

Jan Möbius's avatar
 
Jan Möbius committed
999 1000 1001
void glViewer::moveEvent (QGraphicsSceneMoveEvent *)
{
  glstate_->viewport(scenePos().x(),
Jan Möbius's avatar
Jan Möbius committed
1002 1003 1004
                     scene()->height () - scenePos().y() - size().height (),
                     size().width (), size().height (),
                     scene()->width (), scene()->height ());
Jan Möbius's avatar
 
Jan Möbius committed
1005
  update();
1006

1007
  emit viewChanged();
Jan Möbius's avatar
 
Jan Möbius committed
1008
}
Jan Möbius's avatar
 
Jan Möbius committed
1009 1010 1011

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

1012
void glViewer::encodeView(QString& _view, const QSize& _windowSize /*= QSize()*/, const int _splitterWidth /*=-1*/)
Jan Möbius's avatar
 
Jan Möbius committed
1013
{
1014
  // Get current matrices
Jan Möbius's avatar
 
Jan Möbius committed
1015 1016 1017
  const ACG::GLMatrixd m = glstate_->modelview();
  const ACG::GLMatrixd p = glstate_->projection();

1018
  // Add modelview matrix to output
1019
  _view += QString(COPY_PASTE_VIEW_START_STRING) + "\n";
1020 1021 1022 1023 1024