56 #include <ACG/GL/acg_glew.hh> 58 #include "QtBaseViewer.hh" 59 #include "QtGLViewerLayout.hh" 60 #include "PostProcessing.hh" 62 #include <ACG/QtWidgets/QtWheel.hh> 63 #include <ACG/Scenegraph/CoordsysNode.hh> 65 #include <ACG/Scenegraph/StencilRefNode.hh> 66 #include <ACG/GL/GLError.hh> 67 #include <ACG/GL/IRenderer.hh> 69 #include <QGraphicsWidget> 72 #include <QtNetwork/QUdpSocket> 74 #include <QGraphicsSceneDragDropEvent> 75 #include <QPropertyAnimation> 80 #include <QApplication> 82 #include <QColorDialog> 84 #include <QGraphicsView> 85 #include <QGraphicsProxyWidget> 87 #include <QImageWriter> 90 #include <QOpenGLFramebufferObject> 101 #include <OpenFlipper/common/ViewObjectMarker.hh> 105 #include <OpenFlipper/common/RendererInfo.hh> 106 #include <QOpenGLWidget> 114 static const char COPY_PASTE_VIEW_START_STRING[] =
115 "ACG::QtWidgets::QGLViewerWidget encoded view";
121 OFGLWidget* _glWidget,
123 QGraphicsWidget* _parent) :
124 QGraphicsWidget(_parent),
125 glareaGrabbed_(false),
126 projectionUpdateLocked_(false),
128 glWidget_(_glWidget),
131 mouseCache_(nullptr),
132 updatePickCache_(true),
133 pickCacheSupported_(true),
134 constrainedRotationAxis_(
std::numeric_limits<double>::quiet_NaN(), 0, 0),
135 clickEvent_(QEvent::MouseButtonPress, QPoint (),
Qt::NoButton,
Qt::NoButton,
Qt::NoModifier),
136 properties_(_properties),
139 flyAnimationPerspective_(0),
140 flyAnimationOrthogonal_(0),
142 currentAnimationPos_(0.0),
170 QSizePolicy sp = sizePolicy();
171 sp.setHorizontalPolicy( QSizePolicy::Expanding );
172 sp.setVerticalPolicy( QSizePolicy::Expanding );
173 sp.setHorizontalStretch( 1 );
174 sp.setVerticalStretch( 1 );
177 redrawTime_.start ();
180 timer_ =
new QTimer(
this );
194 setAcceptDrops(
true);
210 deleteGLDebugLogger();
249 unsigned int _maxPasses,
252 const bool _resetTrackBall)
254 sceneGraphRoot_ = _root;
256 if (sceneGraphRoot_ )
262 if ( ( _bbmin[0] > _bbmax[0] ) ||
263 ( _bbmin[1] > _bbmax[1] ) ||
264 ( _bbmin[2] > _bbmax[2] ) ) {
276 if ( ( _bbmax - _bbmin ).max() <
OpenFlipperSettings().value(
"Core/Gui/glViewer/minimalSceneSize",0.1).toDouble() ) {
283 ( _bbmax - _bbmin ).norm() * 0.5,
306 trackMouse_ = _track;
360 emit projectionModeChanged(
true );
362 emit projectionModeChanged(
false );
383 emit navigationModeChanged(
true );
385 emit navigationModeChanged(
false );
390 if(_fovy <= 0.0 || _fovy >= 180) {
391 std::cerr <<
"Error: Minimum or maximum fovy angle exceeded!" << std::endl;
401 if( projectionUpdateLocked_ )
408 const double aspect = _aspect ? _aspect : this->
aspect_ratio();
414 const double fovy = this->field_of_view_vertical();
435 if(_resetTrackBall) {
450 if ( nearPlane <= 0.0 ) {
451 std::cerr <<
"Error in BaseViewer drawScene, nearplane <= 0.0" << std::endl;
452 nearPlane = 0.000000000000001;
456 if ( nearPlane > farPlane ) {
457 std::cerr <<
"Error in BaseViewer setScenePos, Nearplane > Farplane" << std::endl;
458 std::swap(nearPlane,farPlane);
501 if (
glstate_->compatibilityProfile())
505 switch (normalsMode_ = _mode)
540 void glViewer::drawScene(
double _aspect)
559 if ( nearPlane <= 0.0 ) {
560 std::cerr <<
"Error in BaseViewer drawScene, nearplane < 0" << std::endl;
561 nearPlane = 0.000000000000001;
565 if ( nearPlane > farPlane ) {
566 std::cerr <<
"Error in BaseViewer drawScene, Nearplane > Farplane" << std::endl;
567 std::swap(nearPlane,farPlane);
578 if(!
glstate_->compatibilityProfile())
603 GLuint backbufferFbo = 0;
604 GLuint backbufferTarget = 0;
605 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, (GLint*)&backbufferFbo);
606 glGetIntegerv(GL_DRAW_BUFFER, (GLint*)&backbufferTarget);
613 GLint curViewport[4];
614 glGetIntegerv(GL_VIEWPORT, curViewport);
615 glScissor(curViewport[0], curViewport[1], curViewport[2], curViewport[3]);
616 glEnable(GL_SCISSOR_TEST);
617 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
618 glDisable(GL_SCISSOR_TEST);
628 bool stereoOpenGL =
false;
629 bool stereoAnaglyph =
false;
634 stereoOpenGL = OpenFlipper::Options::stereoMode () == OpenFlipper::Options::OpenGL && OpenFlipper::Options::glStereo ();
635 stereoAnaglyph = !stereoOpenGL;
639 if (!stereoOpenGL && !stereoAnaglyph)
657 if (shaderRenderPlugin)
663 if (stereoOpenGL || stereoAnaglyph) {
665 GLuint backbufferFbo = 0;
666 GLuint backbufferTarget = 0;
667 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, (GLint*)&backbufferFbo);
668 glGetIntegerv(GL_DRAW_BUFFER, (GLint*)&backbufferTarget);
675 for (
int eye = 0; eye < 2; ++eye) {
677 if (stereoOpenGL && !numPostProcessors) {
679 glDrawBuffer(eye ? GL_BACK_RIGHT : GL_BACK_LEFT);
680 glEnable(GL_SCISSOR_TEST);
681 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
682 glDisable(GL_SCISSOR_TEST);
697 glBindFramebuffer(GL_FRAMEBUFFER, backbufferFbo);
698 glDrawBuffer(backbufferTarget);
722 glBindFramebuffer(GL_FRAMEBUFFER, backbufferFbo);
723 glDrawBuffer(backbufferTarget);
739 frame_time_ = timer.elapsed();
750 void glViewer::drawScene_mono()
752 if (sceneGraphRoot_) {
755 QSet<GLuint> references;
759 glClear (GL_STENCIL_BUFFER_BIT);
761 glStencilOp (GL_KEEP, GL_KEEP, GL_ZERO);
762 glStencilFunc (GL_ALWAYS, 0, ~0);
774 o_it->stencilRefNode ()->setReference (ref);
775 o_it->stencilRefNode ()->show ();
780 o_it->stencilRefNode ()->hide ();
797 for (
unsigned int i = 0; i <
sizeof (GLuint) * 8; i++)
798 if (refBits & (1 << i))
799 references << (1 << i);
802 glPushAttrib(GL_ALL_ATTRIB_BITS);
807 if (
glstate_->compatibilityProfile())
812 int vp_l, vp_b, vp_w, vp_h;
815 glMatrixMode(GL_PROJECTION);
818 glOrtho(0, vp_w, vp_h, 0, 0, 1.0);
819 glMatrixMode(GL_MODELVIEW);
823 glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
825 foreach (
unsigned int ref, references)
831 unsigned int mask = ~0;
844 glStencilFunc (GL_EQUAL, ref, mask);
847 glColor4f (color[0], color [1], color [2], color[3]);
852 glVertex2i(vp_w, vp_h);
858 glMatrixMode(GL_PROJECTION);
860 glMatrixMode(GL_MODELVIEW);
923 unsigned int maxPases = 1;
980 if (
glstate_->compatibilityProfile())
1000 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
1001 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
1002 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
1003 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1004 glPixelStorei(GL_PACK_ROW_LENGTH, 0);
1005 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
1006 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
1007 glPixelStorei(GL_PACK_ALIGNMENT, 1);
1015 if (sceneGraphRoot_)
1017 unsigned int maxPases = 1;
1021 sceneGraph ( sceneGraphRoot_, maxPases,bbmin,bbmax,
true);
1027 startGLDebugLogger();
1041 if (!
glstate_->compatibilityProfile())
1043 if (!defaultVAO_.isSupported())
1044 std::cerr <<
"Error - using core profile, but required VAO is not supported!" << std::endl;
1054 GLboolean dtenabled;
1055 glGetBooleanv(GL_DEPTH_TEST, &dtenabled);
1058 if (
glstate_->compatibilityProfile())
1060 glPushAttrib(GL_ALL_ATTRIB_BITS);
1063 glMatrixMode(GL_PROJECTION);
1066 glMatrixMode(GL_MODELVIEW);
1082 if (
glstate_->compatibilityProfile())
1083 glColor4f(1.0,0.0,0.0,1.0);
1092 if (
glstate_->compatibilityProfile())
1096 glMatrixMode(GL_PROJECTION);
1106 glBindBuffer(GL_ARRAY_BUFFER, 0);
1107 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1118 scene()->height () - scenePos().y() - size().height (),
1119 size().width (), size().height (),
1120 scene()->width (), scene()->height ());
1129 scene()->height () - scenePos().y() - size().height (),
1130 size().width (), size().height (),
1131 scene()->width (), scene()->height ());
1140 const int _splitterWidth ,
const bool _make_c_string )
1146 static const char *line_delim_c =
" \\\n";
1147 static const char *line_delim_std = line_delim_c + 2;
1148 const char *line_delim = _make_c_string ? line_delim_c : line_delim_std;
1154 _view += QString(COPY_PASTE_VIEW_START_STRING) + line_delim;
1155 _view += QString::number(m(0,0)) +
" " + QString::number(m(0,1)) +
" " + QString::number(m(0,2)) +
" " + QString::number(m(0,3)) + line_delim;
1156 _view += QString::number(m(1,0)) +
" " + QString::number(m(1,1)) +
" " + QString::number(m(1,2)) +
" " + QString::number(m(1,3)) + line_delim;
1157 _view += QString::number(m(2,0)) +
" " + QString::number(m(2,1)) +
" " + QString::number(m(2,2)) +
" " + QString::number(m(2,3)) + line_delim;
1158 _view += QString::number(m(3,0)) +
" " + QString::number(m(3,1)) +
" " + QString::number(m(3,2)) +
" " + QString::number(m(3,3)) + line_delim;
1161 _view += QString::number(p(0,0)) +
" " + QString::number(p(0,1)) +
" " + QString::number(p(0,2)) +
" " + QString::number(p(0,3)) + line_delim;
1162 _view += QString::number(p(1,0)) +
" " + QString::number(p(1,1)) +
" " + QString::number(p(1,2)) +
" " + QString::number(p(1,3)) + line_delim;
1163 _view += QString::number(p(2,0)) +
" " + QString::number(p(2,1)) +
" " + QString::number(p(2,2)) +
" " + QString::number(p(2,3)) + line_delim;
1164 _view += QString::number(p(3,0)) +
" " + QString::number(p(3,1)) +
" " + QString::number(p(3,2)) +
" " + QString::number(p(3,3)) + line_delim;
1167 _view += QString::number(_windowSize.width()) +
" " + QString::number(_windowSize.height()) +
" " + QString::number(_splitterWidth)+
" " + QString::number(projectionMode_) +
" " + QString::number(
properties_.
orthoWidth()) + line_delim;;
1170 _view += QString::fromUtf8(
"%1 %2").arg(size().width()).arg(size().height());
1184 QSize *_windowSize ,
1185 int* _splitterWidth , QSize *_viewportSize)
1188 QString temp = _view;
1189 temp.remove(0,
sizeof(COPY_PASTE_VIEW_START_STRING));
1192 QStringList split = temp.split(QRegExp(
"[\\n\\s]"),QString::SkipEmptyParts);
1195 if ( split.size() >= 37 ) {
1201 for (
int i = 0; i < 4; ++i)
1203 for (
int j = 0; j < 4; ++j)
1205 m(i,j) = split[i*4 + j].toDouble();
1206 p(i,j) = split[i*4 + j +16 ].toDouble();
1216 int w = split[32].toInt();
1217 int h = split[33].toInt();
1218 *_windowSize = QSize(w,h);
1224 if (_splitterWidth) {
1225 *_splitterWidth = split[34].toInt();
1231 pMode = split[35].toInt();
1232 ortho_width = split[36].toDouble();
1234 if (_viewportSize && split.size() >= 39) {
1235 *_viewportSize = QSize(split[37].toInt(), split[38].toInt());
1238 }
else if ( split.size() == 36 ) {
1244 for (
int i = 0; i < 4; ++i)
1246 for (
int j = 0; j < 4; ++j)
1248 m(i,j) = split[i*4 + j].toDouble();
1249 p(i,j) = split[i*4 + j +16].toDouble();
1259 int w = split[32].toInt();
1260 int h = split[33].toInt();
1261 *_windowSize = QSize(w,h);
1268 if (_splitterWidth) {
1269 *_splitterWidth = -1;
1275 pMode = split[34].toInt();
1276 ortho_width = split[35].toDouble();
1279 std::cerr <<
"Unable to paste view ... wrong parameter count!! is" << split.size() << std::endl;
1287 int* _splitterWidth , QSize *_viewportSize)
1289 if (_view.left(
sizeof(COPY_PASTE_VIEW_START_STRING)-1) != QString(COPY_PASTE_VIEW_START_STRING))
1291 std::cerr <<
"No View was copied." << std::endl;
1299 if (!
decodeView(_view, m, p, pMode, ortho_width,
1300 _windowSize, _splitterWidth, _viewportSize))
1324 const bool _make_c_string )
1327 encodeView(view,_windowSize,_splitterWidth, _make_c_string);
1328 QApplication::clipboard()->setText(view);
1338 view = QApplication::clipboard()->text();
1342 void glViewer::actionSetView(QString view) {
1349 glViewer::createWidgets()
1354 wheelZ_->setMinimumSize(wheelZ_->
sizeHint());
1355 wheelZ_->setMaximumSize(wheelZ_->
sizeHint());
1356 connect(wheelZ_,SIGNAL(angleChangedBy(
double)),
1358 wheelZ_->setToolTip( tr(
"Translate along <b>z-axis</b>."));
1359 wheelZ_->setWhatsThis( tr(
"Translate along <b>z-axis</b>."));
1362 wheelY_->setMinimumSize(wheelY_->
sizeHint());
1363 wheelY_->setMaximumSize(wheelY_->
sizeHint());
1364 connect(wheelY_,SIGNAL(angleChangedBy(
double)),
1366 wheelY_->setToolTip(tr(
"Rotate around <b>y-axis</b>."));
1367 wheelY_->setWhatsThis( tr(
"Rotate around <b>y-axis</b>."));
1370 wheelX_->setMinimumSize(wheelX_->
sizeHint());
1371 wheelX_->setMaximumSize(wheelX_->
sizeHint());
1372 connect(wheelX_,SIGNAL(angleChangedBy(
double)),
1374 wheelX_->setToolTip(tr(
"Rotate around <b>x-axis</b>."));
1375 wheelX_->setWhatsThis( tr(
"Rotate around <b>x-axis</b>."));
1381 QGraphicsWidget *wheelX = glScene_->addWidget (wheelX_);
1382 QGraphicsWidget *wheelY = glScene_->addWidget (wheelY_);
1383 QGraphicsWidget *wheelZ = glScene_->addWidget (wheelZ_);
1385 wheelX_->setWindowOpacity (0.5);
1386 wheelY_->setWindowOpacity (0.5);
1387 wheelZ_->setWindowOpacity (0.5);
1389 wheelX->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
1390 wheelY->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
1391 wheelZ->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
1395 glBaseLayout_->addWheelY(wheelY);
1396 glBaseLayout_->addWheelZ(wheelZ);
1398 connect(wheelX_,SIGNAL(hideWheel()),
this,SLOT(slotHideWheels()));
1399 connect(wheelY_,SIGNAL(hideWheel()),
this,SLOT(slotHideWheels()));
1400 connect(wheelZ_,SIGNAL(hideWheel()),
this,SLOT(slotHideWheels()));
1402 setLayout(glBaseLayout_);
1439 glstate_->
rotate(_angle, _axis[0], _axis[1], _axis[2], ACG::MULT_FROM_LEFT);
1452 return size().width();
1455 return size().height();
1458 return QSize(size().width(),size().height());
1461 QPoint p (scene()->views().front()->mapFromGlobal(_pos));
1462 QPointF f (mapFromScene(QPointF(p.x(), p.y ())));
1463 return QPoint (f.x(), f.y());
1467 QPointF f (mapToScene(QPointF(_pos.x(), _pos.y ())));
1468 QPoint p (f.x(), f.y());
1469 return scene()->views().front()->mapToGlobal(p);
1472 double glViewer::field_of_view_vertical()
const {
1511 glareaGrabbed_ =
true;
1515 std::cerr <<
"grabGLArea: Blanking cursorpainter cursor" << std::endl;
1517 setCursor(Qt::BlankCursor);
1518 std::cerr <<
"grabGLArea: Blanking qt cursor" << std::endl;
1526 glareaGrabbed_ =
false;
1533 std::cerr <<
"grabGLArea: Setting cursorPainter cursor to arrow" << std::endl;
1535 setCursor(Qt::ArrowCursor);
1536 std::cerr <<
"grabGLArea: Setting qt cursor to arrow" << std::endl;
1547 glScene_->update ();
1549 QPoint p (_e->pos().x(), _e->pos().y());
1559 QPoint p (_e->scenePos().x(), _e->scenePos().y());
1560 QMouseEvent me(QEvent::MouseButtonPress ,p, _e->screenPos(), _e->button(),
1561 _e->buttons(), _e->modifiers());
1583 glScene_->update ();
1590 case Viewer::ExamineMode:
1591 if ((_e->modifiers() & Qt::ControlModifier))
1608 case Viewer::LightMode:
1612 case Viewer::PickingMode:
1617 case Viewer::QuestionMode:
1632 QPoint p (_e->scenePos().x(), _e->scenePos().y());
1633 QMouseEvent me(QEvent::MouseButtonDblClick ,p, _e->screenPos(), _e->button(),
1634 _e->buttons(), _e->modifiers());
1638 glScene_->update ();
1642 case Viewer::ExamineMode:
1647 case Viewer::LightMode:
1651 case Viewer::PickingMode:
1656 case Viewer::QuestionMode:
1668 QPoint p (_e->scenePos().x(), _e->scenePos().y());
1669 QMouseEvent me(QEvent::MouseMove ,p, _e->screenPos(), _e->button(),
1670 _e->buttons(), _e->modifiers());
1675 case Viewer::ExamineMode:
1679 case Viewer::LightMode:
1683 case Viewer::PickingMode:
1686 if ((_e->buttons() & (Qt::LeftButton | Qt::MidButton | Qt::RightButton))
1694 case Viewer::QuestionMode:
1708 QPoint p (_e->scenePos().x(), _e->scenePos().y());
1709 QMouseEvent me(QEvent::MouseButtonRelease ,p, _e->screenPos(), _e->button(),
1710 _e->buttons(), _e->modifiers());
1720 case Viewer::ExamineMode:
1728 if (abs (diff.x ()) <= 1 && abs (diff.y ()) <= 1 && elapsed <= QApplication::doubleClickInterval () / 2)
1731 clickTimer_.setInterval (QApplication::doubleClickInterval () - elapsed);
1742 case Viewer::LightMode:
1746 case Viewer::PickingMode:
1751 case Viewer::QuestionMode:
1760 isRotating_ =
false;
1769 QPoint p (_e->scenePos().x(), _e->scenePos().y());
1770 QWheelEvent we(p, _e->screenPos(), _e->delta(), _e->buttons(),
1771 _e->modifiers(), _e->orientation());
1776 case Viewer::ExamineMode:
1780 case Viewer::PickingMode:
1788 isRotating_ =
false;
1795 std::cerr <<
"dragEnter" << std::endl;
1797 QPoint p (_e->pos().x(), _e->pos().y());
1798 QDragEnterEvent de(p, _e->possibleActions(), _e->mimeData(), _e->buttons(),
1809 std::cerr <<
"drop" << std::endl;
1811 QPoint p (_e->pos().x(), _e->pos().y());
1812 QDropEvent de(p, _e->possibleActions(), _e->mimeData(), _e->buttons(),
1839 QPointF f(mapFromScene(QPointF(_event->pos().x(), _event->pos().y())));
1840 QPoint pos(f.x(), f.y());
1842 switch (_event->type()) {
1844 case QEvent::MouseButtonPress: {
1850 case QEvent::MouseButtonDblClick: {
1851 flyTo(_event->pos(), _event->button() == Qt::MidButton);
1855 case QEvent::MouseMove: {
1857 if(!lookAround_)
break;
1860 QPoint newpos = QPoint(pos.x() -
glWidth() / 2,
glHeight() / 2 - pos.y());
1863 double x = 2.0 * newpos.x() /
glWidth();
1864 double y = 2.0 * newpos.y() /
glHeight();
1866 double xo = 2.0 * oldpos.x() /
glWidth();
1867 double yo = 2.0 * oldpos.y() /
glHeight();
1869 double diffx = xo - x;
1870 double diffy = yo - y;
1888 case QEvent::MouseButtonRelease: {
1889 lookAround_ =
false;
1904 QPointF f(mapFromScene(QPointF(_event->pos().x(), _event->pos().y())));
1905 QPoint pos(f.x(), f.y());
1907 switch (_event->type()) {
1909 case QEvent::MouseButtonPress: {
1915 GLint x2d = f.x() - scenePos().x();
1916 GLint y2d =
glHeight() - (f.y() - scenePos().y());
1917 glReadPixels (x2d, y2d, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, depth);
1921 if (_event->modifiers() & Qt::ShiftModifier) {
1937 case QEvent::MouseButtonDblClick: {
1938 flyTo(_event->pos(), _event->button() == Qt::MidButton);
1942 case QEvent::MouseMove: {
1943 double factor = 1.0;
1945 if (_event->modifiers() == Qt::ShiftModifier)
1949 if (_event->buttons() & (Qt::LeftButton | Qt::MidButton | Qt::RightButton)) {
1950 QPoint newPoint2D = pos;
1953 bool newPoint_hitSphere =
mapToSphere(newPoint2D, newPoint3D);
1959 if ((_event->buttons() & Qt::LeftButton) && (_event->buttons() & Qt::MidButton)) {
1985 else if ((_event->buttons() & Qt::MidButton) || (!
allowRotation_ && (_event->buttons() & Qt::LeftButton)) ) {
1994 translation =
ACG::Vec3d(value_x * factor, -value_y * factor, 0.0);
1998 GLint x2dEnd = newPoint2D.x() - scenePos().x();
1999 GLint y2dEnd =
glHeight() - (newPoint2D.y() - scenePos().y());
2012 translation = unprojectedEnd - unprojectedStart;
2020 }
else if (
allowRotation_ && (_event->buttons() & Qt::LeftButton)) {
2026 if ((newPoint_hitSphere =
mapToSphere(newPoint2D, newPoint3D))) {
2029 if (fabs(cos_angle) < 1.0) {
2030 angle = acos(cos_angle) * 180.0 / M_PI * factor;
2048 const double dragLength = dragVector.y();
2050 const double angle = -dragLength * factor;
2090 case QEvent::MouseButtonRelease: {
2094 if (isRotating_ && (_event->button() == Qt::LeftButton) && (!(_event->buttons() & Qt::MidButton))
2114 if (_event->modifiers() == Qt::ShiftModifier)
2125 if ( _event->modifiers() & Qt::ControlModifier ) {
2129 double numDegrees = double(_event->delta()) / 8.0;
2130 double numSteps = numDegrees / 15.0;
2175 if ( (_v2D.x() >= 0) && (_v2D.x() < (int)
glWidth()) &&
2176 (_v2D.y() >= 0) && (_v2D.y() < (int)
glHeight()) )
2178 double x = (double)(_v2D.x() - ((double)
glWidth() / 2.0)) / (
double)
glWidth();
2179 double y = (double)(((
double)
glHeight() / 2.0) - _v2D.y()) / (
double)
glHeight();
2180 double sinx = sin(M_PI * x * 0.5);
2181 double siny = sin(M_PI * y * 0.5);
2182 double sinx2siny2 = sinx * sinx + siny * siny;
2186 _v3D[2] = sinx2siny2 < 1.0 ? sqrt(1.0 - sinx2siny2) : 0.0;
2205 static int msecs=0, count=0;
2207 msecs += frame_time_;
2208 if (count >= 10 && msecs >= 500) {
2210 sprintf( s,
"%.3f fps", (1000.0 * count / (
float)msecs) );
2211 emit statusMessage(s,2000);
2228 glFrontFace( GL_CCW );
2230 glFrontFace( GL_CW );
2251 void glViewer::snapshot(QImage& _image,
int _width,
int _height,
bool _alpha,
bool _hideCoordsys,
int samples) {
2254 int w = 0, h = 0, bak_w = 0, bak_h = 0, left = 0, bottom = 0;
2261 double aspect = (double)w / (
double)h;
2264 if(_width != 0 || _height != 0) {
2268 _width = (int)((
double)_height * aspect);
2271 _height = (int)((
double)_width / aspect);
2280 aspect = (double)w / (
double)h;
2286 if ( createQFBO(fb,&hnd,w,h,&samples) ){
2296 bool formerCoordsysState =
true;
2301 node = sceneGraphRoot_->
find(
"Core Coordsys Node");
2303 formerCoordsysState = node->
visible();
2306 emit statusMessage(QString(tr(
"Could not find coordsys node, thus it will appear in the snapshot anyway.")));
2312 newBack =
ACG::Vec4f(backColorBak[0], backColorBak[1], backColorBak[2], (_alpha ? 0.0f : 1.0f));
2315 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
2317 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2323 glEnable(GL_MULTISAMPLE);
2329 glDisable(GL_MULTISAMPLE);
2334 int testSamples = -1;
2335 createQFBO(temp, &tempHnd, w, h, &testSamples);
2340 QRect rect(QPoint(0, 0), QSize(w,h));
2342 blitQFBO(temp, rect, fb, rect);
2347 _image = QImage(w,h,QImage::Format_ARGB32);
2348 glReadPixels(0,0,w,h,GL_BGRA,GL_UNSIGNED_INT_8_8_8_8_REV,reinterpret_cast<void*>(_image.bits()));
2349 _image = _image.mirrored(
false,
true);
2362 node = sceneGraphRoot_->
find(
"Core Coordsys Node");
2363 if(node != 0 && formerCoordsysState) {
2374 if(_width != 0 || _height != 0) {
2389 snapshot(image, _width, _height, _alpha, _hideCoordsys, samples);
2395 if (!comments.isEmpty())
2396 image.setText(
"Mesh Comments", comments);
2399 image.setText(
"View", view);
2405 QImageWriter writer(fname);
2408 bool rval = writer.canWrite();
2410 writer.write(image);
2413 emit statusMessage (QString(tr(
"Snapshot: "))+fname,5000);
2415 emit statusMessage (QString(tr(
"Could not save snapshot to ")) + fname + QString(tr(
" Error: ")) + writer.errorString() );
2418 void glViewer::slotHideWheels() {
2435 void glViewer::slotShowWheels() {
2452 bool glViewer::wheelsVisible() {
2475 if (!
initialized_ || !sceneGraphRoot_ || !isVisible ())
2481 size_t targetIdx = 0;
2587 double l, r, t, b, w, h, a, radians, wd2, ndfl, zerop, xrange;
2589 w = double(_viewportWidth);
2590 h = double(_viewportHeight);
2594 radians = fovy * 0.5 / 180.0 * M_PI;
2595 wd2 = _properties.
nearPlane() * tan(radians);
2597 ndfl = _properties.
nearPlane() / zerop ;
2598 xrange = a * wd2 * 2 * zerop / _properties.
nearPlane();
2606 double offset2 = offset * ndfl;
2619 _outRight->
translate(-offset, 0.0, 0.0);
virtual void toggleProjectionMode()
toggle projection mode
double near_plane() const
Returns a chili cheese burger.
void animation(bool _state)
set 2-sided lighting on/off
static void enable(GLenum _cap, bool _warnRemoved=true)
replaces glEnable, but supports locking
double sceneRadius()
Get radius of the current scene.
virtual void slotWheelY(double _dAngle)
process signals from wheelX_
unsigned int glWidth() const
get width of QGLWidget
void reset_modelview()
reset modelview matrix (load identity)
static void blendFuncSeparate(GLenum _srcRGB, GLenum _dstRGB, GLenum _srcAlpha, GLenum _dstAlpha)
replaces glBlendFuncSeparate, supports locking
Vec3d viewing_direction() const
get viewing ray
glViewer(QGraphicsScene *_scene, OFGLWidget *_glWidget, Viewer::ViewerProperties &_properties, QGraphicsWidget *_parent=0)
NormalsMode normalsMode() const
get treatment of normals
ACG::Vec3d unproject(const ACG::Vec3d &pt)
Framebuffer object that holds the pick cache.
void pop_modelview_matrix()
pop modelview matrix
double nearPlane()
Return distance to near Plane.
virtual void flyTo(const QPoint &_pos, bool _moveBack)
Animated flight to or away from a given point.
void set_clear_color(const Vec4f &_col)
set background color
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *_event)
handle mouse release events
static void shadeModel(GLenum _mode)
replaces glShadeModel, supports locking
void trackMouse(bool _track)
Enable/disable mouse tracking (move events with no button press)
void resolveStereoAnyglyph(int _viewerID)
Resolve stereo buffers as anaglyph.
QSize glSize() const
get size of QGLWIdget
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *_event)
handle mouse move events
void setScenePos(const ACG::Vec3d &_center, double _radius, const bool _resetTrackBall=false)
QMouseEvent clickEvent_
mouse interaction position
bool updatePickCache_
Should the pick cache be updated.
double far_plane() const
Returns a peanut butter sandwich.
bool enabled()
Returns true if cursor painting is enabled and compatible cursor is set.
void twoSidedLighting(bool _state)
set 2-sided lighting on/off
QPoint glMapFromGlobal(const QPoint &_pos) const
map global to glarea coords
Vec3d up() const
get up-vector w.r.t. camera coordinates
void viewport(int _left, int _bottom, int _width, int _height, int _glwidth=0, int _glheight=0)
set viewport (lower left corner, width, height, glcontext width, height)
void updateCursorPosition(QPointF _scenePos)
will be called from CursorPainter to inform the viewer that the cursor position changed ...
void signalWheelEvent(QWheelEvent *, const std::string &)
Emitted in Pick mode. Uses pick mode.
virtual bool blendForStencilRefBit(GLuint _refbit, GLenum &_src, GLenum &_dst, ACG::Vec4f &_color)
void actionPasteView(QSize *_windowSize=NULL, int *_splitterWidth=NULL)
void setPlanes(double _near, double _far)
Set near and far plane at the same time.
double wheelZoomFactorShift()
Zoom factor when using mouse wheel and pressing shift.
void signalSceneGraphChanged(ACG::SceneGraph::BaseNode *_root)
scene graph has changed
void encodeView(QString &_view, const QSize &_windowSize=QSize(-1,-1), const int _toolBarWidth=-1, const bool _make_c_string=false)
virtual void makeCurrent()
Makes this widget the current widget for OpenGL operations.
int viewport_width() const
get viewport width
void signalMakeActive()
make this widget active
void push_projection_matrix()
push projection matrix
void setglState(ACG::GLState *_glState)
Pointer to the glState of the Viewer.
void rotate(const ACG::Vec3d &axis, double angle)
rotate the scene (around its center) and update modelview matrix
void viewWheelEvent(QWheelEvent *_event)
specialized viewer: handle wheel events
Vec3d project(const Vec3d &_point) const
project point in world coordinates to window coordinates
void strafeLeft()
First person navigation: Strafe left.
VectorT< float, 4 > Vec4f
unsigned int glHeight() const
get height of QGLWidget
static void lockBlendFuncSeparate(bool _rgb=true, bool _alpha=true)
lock blend func
ACG::Vec3d constrainedRotationAxis_
mouse interaction position
virtual void render(ACG::GLState *_glState, Viewer::ViewerProperties &_properties)
rendering function
void show()
Show node: set status to Active.
static void bindTexture(GLenum _target, GLuint _buffer)
replaces glBindTexture, supports locking
virtual void moveEvent(QGraphicsSceneMoveEvent *_e)
handle move events
ACG::SceneGraph::BaseNode * getSceneGraphRootNode()
get scenegraph root node
void drawMode(ACG::SceneGraph::DrawModes::DrawMode _mode)
set draw mode (No test if this mode is available!)
NavigationMode navigationMode() const
get current navigation mode
Viewer::ViewerProperties * properties()
Returns a pointer to the Viewer Status.
void setProjectionMode(const ProjectionMode _mode)
set mode to either ORTHOGRAPHIC_PROJECTION or PERSPECTIVE_PROJECTION
void get_viewport(int &_left, int &_bottom, int &_width, int &_height) const
get viewport
void setCoordSysProjection(glViewer::ProjectionMode _mode)
helper function for setting the projection mode of the coordinate system node
Viewer::ActionMode actionMode()
get the action mode
void translate(Scalar _x, Scalar _y, Scalar _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply self with translation matrix (x,y,z)
ACG::Vec3d trackballCenter()
Get virtual trackball center (rotation center when using mouse)
int setupScene(int _viewerID, int _width, int _height, int _samples=0, int _stereoEye=-1)
Bind fbo for scene rendering.
void startDragEvent(QMouseEvent *_event)
QStringList collectObjectComments(bool visibleOnly, bool targetedOnly)
void identity()
setup an identity matrix
virtual void resizeEvent(QGraphicsSceneResizeEvent *_e)
handle resize events
const QStringList ALL_OBJECTS
Iterable object range.
double trackballRadius()
Get trackball radius (rotation sphere when using mouse)
CursorPainter * cursorPainter()
Flag if stereo should be enabled for the current viewer.
RendererInfo * active(int _id)
Get the current active renderer.
virtual void viewAll()
view the whole scene
bool fast_pick(const QPoint &_mousePos, ACG::Vec3d &_hitPoint)
ACG::Vec3d lastPoint3D_
mouse interaction position
void translate(const ACG::Vec3d &trans)
translate the scene and update modelview matrix
void signalMouseEvent(QMouseEvent *, const std::string &)
VectorT< T, 3 > transform_point(const VectorT< T, 3 > &_v) const
transform point (x',y',z',1) = M * (x,y,z,1)
double wheelZoomFactor()
Zoom factor when using mouse wheel.
void actionCopyView(const QSize &_windowSize=QSize(-1,-1), const int _splitterWidth=-1, const bool _make_c_string=false)
void traverse_multipass(BaseNode *_node, Action &_action, const unsigned int &_pass)
ProjectionMode projectionMode() const
get current projection mode
void viewChanged()
This signal is emitted whenever the view is changed by the user.
void viewingDirection(const ACG::Vec3d &_dir, const ACG::Vec3d &_up)
set the viewing direction
ACG::Vec3d lastRotationAxis_
mouse interaction position
virtual void setFOVY(double _fovy)
Set fovy.
virtual void orthographicProjection()
set orthographic view (projectionMode(ORTHOGRAPHIC_PROJECTION))
QPoint glMapToGlobal(const QPoint &_pos) const
map glarea coords to global coords
void postProcess(int _viewerID, ACG::GLState *_glstate, const ACG::GLMatrixd &_modelview, const ACG::GLMatrixd &_proj1, const ACG::GLMatrixd &_proj2, bool _hwOpenGLStereo=false)
Perform all post processing.
bool backFaceCulling()
Get current state of backface culling.
void set_bounding_box(ACG::Vec3d _min, ACG::Vec3d _max)
static GLuint getFramebufferDraw()
get current draw framebuffer of a target
void objectMarker(ViewObjectMarker *_marker)
set object marker for viewer
virtual void paintGL(double _aspect=0.0)
draw the scene. Triggered by updateGL().
void signalMouseEventClick(QMouseEvent *, bool _double)
void reset_projection()
reset projection matrix (load identity)
DLLEXPORT ObjectIterator objectsEnd()
Return Iterator to Object End.
virtual void mousePressEvent(QGraphicsSceneMouseEvent *_event)
handle mouse press events
NavigationMode
Navigation mode.
virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *_event)
handle mouse double click events
Vec3d unproject(const Vec3d &_winPoint) const
unproject point in window coordinates _winPoint to world coordinates
double lastRotationAngle_
mouse interaction position
virtual void perspectiveProjection()
set perspective view (projectionMode(PERSPECTIVE_PROJECTION))
virtual void slotWheelZ(double _dist)
process signals from wheelZ_
Mark per returned reference bits.
void push_modelview_matrix()
push modelview matrix
void set_modelview(const GLMatrixd &_m)
set modelview
QTime lastMoveTime_
mouse interaction position
bool initialized_
Have the viewer gl properties been initalized.
void perspective(double _fovY, double _aspect, double _near_plane, double _far_plane)
perspective projection
Vec3d right() const
get right-vector w.r.t. camera coordinates
void set_msSinceLastRedraw(unsigned int _ms)
set time passed since last redraw in milliseconds
ProjectionMode
projection mode
const GLMatrixd & inverse_modelview() const
get inverse modelview matrix
NormalsMode
Automatically normalize normals?
virtual bool stencilRefForObject(BaseObjectData *_obj, GLuint &_reference)=0
virtual void setHome()
set home position
void slotPropertiesUpdated()
static void disable(GLenum _cap, bool _warnRemoved=true)
replaces glDisable, but supports locking
bool allowConstrainedRotation()
mouse interaction position
virtual void setView(const ACG::GLMatrixd &_modelview, const ACG::GLMatrixd &_inverse_modelview)
set view, used for synchronizing
void slotClickTimeout()
Handle click timeout.
void setCursor(const QCursor &_cursor)
Sets the current used cursor.
QRectF cursorBoundingBox()
Bounding box of the cursor.
void allow_multisampling(bool _b)
Disable multisampling globally.
void viewMouseEvent(QMouseEvent *_event)
specialized viewer: hande mouse events
void moveForward()
First person navigation: Move forward.
static bool decodeView(const QString &_view, ACG::GLMatrixd &m, ACG::GLMatrixd &p, int &pMode, double &ortho_width, QSize *_windowSize=NULL, int *_splitterWidth=NULL, QSize *_viewportSize=NULL)
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
pick any of the prior targets (should be implemented for all nodes)
void ortho(double _left, double _right, double _bottom, double _top, double _near_plane, double _far_plane)
orthographic projection
void setCoreProfileMode(bool _enable)
Tell renderer to use core or compatibility profile.
void signalMouseEventIdentify(QMouseEvent *)
double ortho_width() const
Get width of the gl scene in orthogonal projection mode.
void analyzeSceneGraph(ACG::SceneGraph::BaseNode *_root, unsigned int &_maxPasses, ACG::Vec3d &_bbmin, ACG::Vec3d &_bbmax)
Analyze the SceneGraph <ACG/Scenegraph/SceneGraphAnalysis.hh>
virtual bool blendForStencilRefNumber(GLuint _reference, GLenum &_src, GLenum &_dst, ACG::Vec4f &_color)
bool wheelInvert()
Invert mouse wheel direction?
int viewport_height() const
get viewport height
void hide()
Hide Node: set status to HideNode.
void updateProjectionMatrix(double _aspect=0.0)
updates projection matrix
VectorT< T, 3 > transform_vector(const VectorT< T, 3 > &_v) const
transform vector (x',y',z',0) = A * (x,y,z,0)
ACG::Vec3d cursorPoint3D()
Flag if stereo should be enabled for the current viewer.
void paintCursor(ACG::GLState *_state)
Cursor painting function. The _state has to be setup that 0,0,0 is at the cursor position.
void set_max_render_passes(const unsigned int _max)
set maximum number of render passes
void handleNormalNavigation(QMouseEvent *_event)
Navigate through scene if normal mode has been selected.
void snapshotCounter(const int _counter)
ACG::Vec4f backgroundColor()
Get current background color.
void addWheelX(QGraphicsWidget *_item)
Add Wheel Widget to Layout.
void pop_projection_matrix()
pop projection matrix
void clearBuffers()
clear buffers viewport rectangle
static void blendFunc(GLenum _sfactor, GLenum _dfactor)
replaces glBlendFunc, supports locking
void setCursorPainter(CursorPainter *_cursorPainter)
sets the current cursor painter
static GLuint getFramebufferRead()
get current read framebuffer of a target
virtual void toggleNavigationMode()
toggle navigation mode
void signalCustomContextMenuRequested(const QPoint &)
void stereo(bool _stereo)
Flag if stereo should be enabled for the current viewer.
QPoint lastPoint2D_
mouse interaction position
void rotate(double _angle, double _x, double _y, double _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
rotate around axis (_x, _y, _z) by _angle
QFramebufferObject * mouseCache_
Framebuffer object that holds the pick cache.
use provided normals as is
void viewUpdated()
This signal is emitted when the scene is repainted due to any event.
void signalMouseEventLight(QMouseEvent *)
void drawCursor()
draw the cursor
void strafeRight()
First person navigation: Strafe Right.
virtual void snapshot(int _width=0, int _height=0, bool _alpha=false, bool _hideCoordsys=false, int samples=1)
bool mapToSphere(const QPoint &_p, ACG::Vec3d &_result) const
virtual trackball: map 2D screen point to unit sphere
bool lastPoint_hitSphere_
mouse interaction position
void slotAnimation()
mouse interaction position
void multisampling(bool _state)
set multisampling on/off
unsigned int activeId(int _id)
Get the id of the active renderer.
void lookAt(const ACG::Vec3d &_eye, const ACG::Vec3d &_center, const ACG::Vec3d &_up)
Set look at transformation directly.
bool visible()
Is node visible (status == Active)?
void unLockUpdate()
Unlock display locked by updateLock().
double fovyModifier_
mouse interaction position
float startDepth_
mouse interaction depth
std::string pickMode()
get active pick mode
int numActive(int _id)
Get the number of active post processors for viewer.
void snapshotFileType(const QString &_type)
virtual void initializeGL()
Return a resonable size hint.
virtual void slotWheelX(double _dAngle)
process signals from wheelX_
bool cursorPositionValid()
Flag if stereo should be enabled for the current viewer.
const GLMatrixd & modelview() const
get modelview matrix
void handleFirstPersonNavigation(QMouseEvent *_event)
Navigate through scene if first person mode has been selected.
void grabGLArea()
get all Mouse & Key Events for GlWidget
void initModelviewMatrix()
initialize modelview matrix to identity
virtual void dragEnterEvent(QGraphicsSceneDragDropEvent *_e)
drag & drop for modelview copying
int viewerId()
Get the id of the viewer this viewerproperties belongs to.
virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *_e)
handle mouse press events
QTimer * timer_
mouse interaction position
virtual void updateGL()
Redraw scene. Triggers paint event for updating the view (cf. drawNow()).
double aspect_ratio() const
Returns the viewer's aspect ratio.
static void bindFramebuffer(GLenum _target, GLuint _framebuffer)
replaces glBindFramebuffer, supports locking
ChildIter find(BaseNode *_node)
void set_projection(const GLMatrixd &_m)
set projection
void frustum(Scalar left, Scalar right, Scalar bottom, Scalar top, Scalar near_plane, Scalar far_plane)
multiply self with a perspective projection matrix
void setValue(const QString &key, const QVariant &value)
Wrapper function which makes it possible to enable Debugging output with -DOPENFLIPPER_SETTINGS_DEBUG...
ACG::Vec3d sceneCenter()
Get current scene center (rendering center)
Interface to add additional rendering functions from within plugins.
void set_twosided_lighting(bool _b)
set whether transparent or solid objects should be drawn
virtual ~glViewer()
Destructor.
void setState()
set the whole stored gl state
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.
QOpenGLFramebufferObject QFramebufferObject
Framebuffer object that holds the pick cache.
static void drawBuffer(GLenum _mode)
replaces glDrawBuffer, supports locking
void releaseGLArea()
undo grabbing GLArea
void lookAt(const Vec3d &_eye, const Vec3d &_center, const Vec3d &_up)
set camera by lookAt
void setViewerID(int _viewerID)
Set currently active viewer id.
const GLMatrixd & projection() const
get projection matrix
virtual void dropEvent(QGraphicsSceneDragDropEvent *_e)
drag & drop for modelview copying
bool allowRotation_
mouse interaction position
virtual void home()
go to home pos
static void unlockBlendFuncSeparate()
unlock blend func
QTime clickTime_
mouse interaction position
virtual void wheelEvent(QGraphicsSceneWheelEvent *_event)
handle mouse wheel events
double orthoWidth()
Get width of the gl scene in orthogonal projection mode (defaults to 2.0)
const DataType DATA_ALL(UINT_MAX)
Identifier for all available objects.
static void bindBuffer(GLenum _target, GLuint _buffer)
replaces glBindBuffer, supports locking
Viewer::ViewerProperties & properties_
All properties for this viewer.
Vec3d eye() const
get eye point
void moveBack()
First person navigation: Move back.
void computeProjStereo(int _width, int _height, Viewer::ViewerProperties &_properties, ACG::GLMatrixd *_outLeft, ACG::GLMatrixd *_outRight)
Compute left and right eye projection matrix for stereo rendering.
void translate(double _x, double _y, double _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
translate by (_x, _y, _z)
QTimer clickTimer_
mouse interaction position
static void activeTexture(GLenum _texunit)
replaces glActiveTexture, no locking support
void sceneGraph(ACG::SceneGraph::BaseNode *_root, unsigned int _maxPasses, ACG::Vec3d _bbmin, ACG::Vec3d _bbmax, const bool _resetTrackBall=false)
void initialize()
initialize all state variables (called by constructor)
VectorT< double, 3 > Vec3d
ACG::GLState * glstate_
Gl State.
PostProcessing * postproc_
Post-Processing executor.
double farPlane()
Return distance to far Plane.
bool pick(ACG::SceneGraph::PickTarget _pickTarget, const QPoint &_mousePos, size_t &_nodeIdx, size_t &_targetIdx, ACG::Vec3d *_hitPointPtr=0)