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),
129 glDebugLogger_(nullptr),
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_(nullptr),
140 flyAnimationOrthogonal_(nullptr),
142 currentAnimationPos_(0.0),
159 sceneGraphRoot_ =
nullptr;
170 QSizePolicy sp = sizePolicy();
171 sp.setHorizontalPolicy( QSizePolicy::Expanding );
172 sp.setVerticalPolicy( QSizePolicy::Expanding );
173 sp.setHorizontalStretch( 1 );
174 sp.setVerticalStretch( 1 );
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;
318 if (node !=
nullptr) {
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 backbufferFbo1 = 0;
666 GLuint backbufferTarget1 = 0;
667 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, (GLint*)&backbufferFbo1);
668 glGetIntegerv(GL_DRAW_BUFFER, (GLint*)&backbufferTarget1);
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, backbufferFbo1);
698 glDrawBuffer(backbufferTarget1);
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);
773 o_it->stencilRefNode ()->setReference (ref);
774 o_it->stencilRefNode ()->show ();
779 o_it->stencilRefNode ()->hide ();
796 for (
unsigned int i = 0; i <
sizeof (GLuint) * 8; i++)
797 if (refBits & (1 << i))
798 references << (1 << i);
801 glPushAttrib(GL_ALL_ATTRIB_BITS);
806 if (
glstate_->compatibilityProfile())
811 int vp_l, vp_b, vp_w, vp_h;
814 glMatrixMode(GL_PROJECTION);
817 glOrtho(0, vp_w, vp_h, 0, 0, 1.0);
818 glMatrixMode(GL_MODELVIEW);
822 glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
824 foreach (
unsigned int ref, references)
830 unsigned int mask = ~0;
843 glStencilFunc (GL_EQUAL, ref, mask);
846 glColor4f (color[0], color [1], color [2], color[3]);
851 glVertex2i(vp_w, vp_h);
857 glMatrixMode(GL_PROJECTION);
859 glMatrixMode(GL_MODELVIEW);
922 unsigned int maxPases = 1;
979 if (
glstate_->compatibilityProfile())
999 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
1000 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
1001 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
1002 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1003 glPixelStorei(GL_PACK_ROW_LENGTH, 0);
1004 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
1005 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
1006 glPixelStorei(GL_PACK_ALIGNMENT, 1);
1014 if (sceneGraphRoot_)
1016 unsigned int maxPases = 1;
1020 sceneGraph ( sceneGraphRoot_, maxPases,bbmin,bbmax,
true);
1026 startGLDebugLogger();
1040 if (!
glstate_->compatibilityProfile())
1042 if (!defaultVAO_.isSupported())
1043 std::cerr <<
"Error - using core profile, but required VAO is not supported!" << std::endl;
1053 GLboolean dtenabled;
1054 glGetBooleanv(GL_DEPTH_TEST, &dtenabled);
1057 if (
glstate_->compatibilityProfile())
1059 glPushAttrib(GL_ALL_ATTRIB_BITS);
1062 glMatrixMode(GL_PROJECTION);
1065 glMatrixMode(GL_MODELVIEW);
1081 if (
glstate_->compatibilityProfile())
1082 glColor4f(1.0,0.0,0.0,1.0);
1091 if (
glstate_->compatibilityProfile())
1095 glMatrixMode(GL_PROJECTION);
1105 glBindBuffer(GL_ARRAY_BUFFER, 0);
1106 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1117 scene()->height () - scenePos().y() - size().height (),
1118 size().width (), size().height (),
1119 scene()->width (), scene()->height ());
1128 scene()->height () - scenePos().y() - size().height (),
1129 size().width (), size().height (),
1130 scene()->width (), scene()->height ());
1139 const int _splitterWidth ,
const bool _make_c_string )
1145 static const char *line_delim_c =
" \\\n";
1146 static const char *line_delim_std = line_delim_c + 2;
1147 const char *line_delim = _make_c_string ? line_delim_c : line_delim_std;
1153 _view += QString(COPY_PASTE_VIEW_START_STRING) + line_delim;
1154 _view += QString::number(m(0,0)) +
" " + QString::number(m(0,1)) +
" " + QString::number(m(0,2)) +
" " + QString::number(m(0,3)) + line_delim;
1155 _view += QString::number(m(1,0)) +
" " + QString::number(m(1,1)) +
" " + QString::number(m(1,2)) +
" " + QString::number(m(1,3)) + line_delim;
1156 _view += QString::number(m(2,0)) +
" " + QString::number(m(2,1)) +
" " + QString::number(m(2,2)) +
" " + QString::number(m(2,3)) + line_delim;
1157 _view += QString::number(m(3,0)) +
" " + QString::number(m(3,1)) +
" " + QString::number(m(3,2)) +
" " + QString::number(m(3,3)) + line_delim;
1160 _view += QString::number(p(0,0)) +
" " + QString::number(p(0,1)) +
" " + QString::number(p(0,2)) +
" " + QString::number(p(0,3)) + line_delim;
1161 _view += QString::number(p(1,0)) +
" " + QString::number(p(1,1)) +
" " + QString::number(p(1,2)) +
" " + QString::number(p(1,3)) + line_delim;
1162 _view += QString::number(p(2,0)) +
" " + QString::number(p(2,1)) +
" " + QString::number(p(2,2)) +
" " + QString::number(p(2,3)) + line_delim;
1163 _view += QString::number(p(3,0)) +
" " + QString::number(p(3,1)) +
" " + QString::number(p(3,2)) +
" " + QString::number(p(3,3)) + line_delim;
1166 _view += QString::number(_windowSize.width()) +
" " + QString::number(_windowSize.height()) +
" " + QString::number(_splitterWidth)+
" " + QString::number(projectionMode_) +
" " + QString::number(
properties_.
orthoWidth()) + line_delim;;
1169 _view += QString::fromUtf8(
"%1 %2").arg(size().width()).arg(size().height());
1183 QSize *_windowSize ,
1184 int* _splitterWidth , QSize *_viewportSize)
1187 QString temp = _view;
1188 temp.remove(0,
sizeof(COPY_PASTE_VIEW_START_STRING));
1191 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) 1192 QStringList split = temp.split(QRegExp(
"[\\n\\s]"),QString::SkipEmptyParts);
1194 QStringList split = temp.split(QRegExp(
"[\\n\\s]"),Qt::SkipEmptyParts);
1198 if ( split.size() >= 37 ) {
1204 for (
int i = 0; i < 4; ++i)
1206 for (
int j = 0; j < 4; ++j)
1208 m(i,j) = split[i*4 + j].toDouble();
1209 p(i,j) = split[i*4 + j +16 ].toDouble();
1219 int w = split[32].toInt();
1220 int h = split[33].toInt();
1221 *_windowSize = QSize(w,h);
1227 if (_splitterWidth) {
1228 *_splitterWidth = split[34].toInt();
1234 pMode = split[35].toInt();
1235 ortho_width = split[36].toDouble();
1237 if (_viewportSize && split.size() >= 39) {
1238 *_viewportSize = QSize(split[37].toInt(), split[38].toInt());
1241 }
else if ( split.size() == 36 ) {
1247 for (
int i = 0; i < 4; ++i)
1249 for (
int j = 0; j < 4; ++j)
1251 m(i,j) = split[i*4 + j].toDouble();
1252 p(i,j) = split[i*4 + j +16].toDouble();
1262 int w = split[32].toInt();
1263 int h = split[33].toInt();
1264 *_windowSize = QSize(w,h);
1271 if (_splitterWidth) {
1272 *_splitterWidth = -1;
1278 pMode = split[34].toInt();
1279 ortho_width = split[35].toDouble();
1282 std::cerr <<
"Unable to paste view ... wrong parameter count!! is" << split.size() << std::endl;
1290 int* _splitterWidth , QSize *_viewportSize)
1292 if (_view.left(
sizeof(COPY_PASTE_VIEW_START_STRING)-1) != QString(COPY_PASTE_VIEW_START_STRING))
1294 std::cerr <<
"No View was copied." << std::endl;
1302 if (!
decodeView(_view, m, p, pMode, ortho_width,
1303 _windowSize, _splitterWidth, _viewportSize))
1327 const bool _make_c_string )
1330 encodeView(view,_windowSize,_splitterWidth, _make_c_string);
1331 QApplication::clipboard()->setText(view);
1341 view = QApplication::clipboard()->text();
1345 void glViewer::actionSetView(QString view) {
1352 glViewer::createWidgets()
1357 wheelZ_->setMinimumSize(wheelZ_->
sizeHint());
1358 wheelZ_->setMaximumSize(wheelZ_->
sizeHint());
1359 connect(wheelZ_,SIGNAL(angleChangedBy(
double)),
1361 wheelZ_->setToolTip( tr(
"Translate along <b>z-axis</b>."));
1362 wheelZ_->setWhatsThis( tr(
"Translate along <b>z-axis</b>."));
1365 wheelY_->setMinimumSize(wheelY_->
sizeHint());
1366 wheelY_->setMaximumSize(wheelY_->
sizeHint());
1367 connect(wheelY_,SIGNAL(angleChangedBy(
double)),
1369 wheelY_->setToolTip(tr(
"Rotate around <b>y-axis</b>."));
1370 wheelY_->setWhatsThis( tr(
"Rotate around <b>y-axis</b>."));
1373 wheelX_->setMinimumSize(wheelX_->
sizeHint());
1374 wheelX_->setMaximumSize(wheelX_->
sizeHint());
1375 connect(wheelX_,SIGNAL(angleChangedBy(
double)),
1377 wheelX_->setToolTip(tr(
"Rotate around <b>x-axis</b>."));
1378 wheelX_->setWhatsThis( tr(
"Rotate around <b>x-axis</b>."));
1384 QGraphicsWidget *wheelX = glScene_->addWidget (wheelX_);
1385 QGraphicsWidget *wheelY = glScene_->addWidget (wheelY_);
1386 QGraphicsWidget *wheelZ = glScene_->addWidget (wheelZ_);
1388 wheelX_->setWindowOpacity (0.5);
1389 wheelY_->setWindowOpacity (0.5);
1390 wheelZ_->setWindowOpacity (0.5);
1392 wheelX->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
1393 wheelY->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
1394 wheelZ->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
1398 glBaseLayout_->addWheelY(wheelY);
1399 glBaseLayout_->addWheelZ(wheelZ);
1401 connect(wheelX_,SIGNAL(hideWheel()),
this,SLOT(slotHideWheels()));
1402 connect(wheelY_,SIGNAL(hideWheel()),
this,SLOT(slotHideWheels()));
1403 connect(wheelZ_,SIGNAL(hideWheel()),
this,SLOT(slotHideWheels()));
1405 setLayout(glBaseLayout_);
1442 glstate_->
rotate(_angle, _axis[0], _axis[1], _axis[2], ACG::MULT_FROM_LEFT);
1455 return size().width();
1458 return size().height();
1461 return QSize(size().width(),size().height());
1464 QPoint p (scene()->views().front()->mapFromGlobal(_pos));
1465 QPointF f (mapFromScene(QPointF(p.x(), p.y ())));
1466 return QPoint (f.x(), f.y());
1470 QPointF f (mapToScene(QPointF(_pos.x(), _pos.y ())));
1471 QPoint p (f.x(), f.y());
1472 return scene()->views().front()->mapToGlobal(p);
1475 double glViewer::field_of_view_vertical()
const {
1514 glareaGrabbed_ =
true;
1518 std::cerr <<
"grabGLArea: Blanking cursorpainter cursor" << std::endl;
1520 setCursor(Qt::BlankCursor);
1521 std::cerr <<
"grabGLArea: Blanking qt cursor" << std::endl;
1529 glareaGrabbed_ =
false;
1536 std::cerr <<
"grabGLArea: Setting cursorPainter cursor to arrow" << std::endl;
1538 setCursor(Qt::ArrowCursor);
1539 std::cerr <<
"grabGLArea: Setting qt cursor to arrow" << std::endl;
1550 glScene_->update ();
1552 QPoint p (_e->pos().x(), _e->pos().y());
1562 QPoint p (_e->scenePos().x(), _e->scenePos().y());
1563 QMouseEvent me(QEvent::MouseButtonPress ,p, _e->screenPos(), _e->button(),
1564 _e->buttons(), _e->modifiers());
1586 glScene_->update ();
1593 case Viewer::ExamineMode:
1594 if ((_e->modifiers() & Qt::ControlModifier))
1611 case Viewer::LightMode:
1615 case Viewer::PickingMode:
1620 case Viewer::QuestionMode:
1635 QPoint p (_e->scenePos().x(), _e->scenePos().y());
1636 QMouseEvent me(QEvent::MouseButtonDblClick ,p, _e->screenPos(), _e->button(),
1637 _e->buttons(), _e->modifiers());
1641 glScene_->update ();
1645 case Viewer::ExamineMode:
1650 case Viewer::LightMode:
1654 case Viewer::PickingMode:
1659 case Viewer::QuestionMode:
1671 QPoint p (_e->scenePos().x(), _e->scenePos().y());
1672 QMouseEvent me(QEvent::MouseMove ,p, _e->screenPos(), _e->button(),
1673 _e->buttons(), _e->modifiers());
1678 case Viewer::ExamineMode:
1682 case Viewer::LightMode:
1686 case Viewer::PickingMode:
1689 if ((_e->buttons() & (Qt::LeftButton | Qt::MidButton | Qt::RightButton))
1697 case Viewer::QuestionMode:
1711 QPoint p (_e->scenePos().x(), _e->scenePos().y());
1712 QMouseEvent me(QEvent::MouseButtonRelease ,p, _e->screenPos(), _e->button(),
1713 _e->buttons(), _e->modifiers());
1723 case Viewer::ExamineMode:
1731 if (abs (diff.x ()) <= 1 && abs (diff.y ()) <= 1 && elapsed <= QApplication::doubleClickInterval () / 2)
1734 clickTimer_.setInterval (QApplication::doubleClickInterval () - elapsed);
1745 case Viewer::LightMode:
1749 case Viewer::PickingMode:
1754 case Viewer::QuestionMode:
1763 isRotating_ =
false;
1772 QPoint p (_e->scenePos().x(), _e->scenePos().y());
1773 QWheelEvent we(p, _e->screenPos(), _e->delta(), _e->buttons(),
1774 _e->modifiers(), _e->orientation());
1779 case Viewer::ExamineMode:
1783 case Viewer::PickingMode:
1791 isRotating_ =
false;
1798 std::cerr <<
"dragEnter" << std::endl;
1800 QPoint p (_e->pos().x(), _e->pos().y());
1801 QDragEnterEvent de(p, _e->possibleActions(), _e->mimeData(), _e->buttons(),
1812 std::cerr <<
"drop" << std::endl;
1814 QPoint p (_e->pos().x(), _e->pos().y());
1815 QDropEvent de(p, _e->possibleActions(), _e->mimeData(), _e->buttons(),
1842 QPointF f(mapFromScene(QPointF(_event->pos().x(), _event->pos().y())));
1843 QPoint pos(f.x(), f.y());
1845 switch (_event->type()) {
1847 case QEvent::MouseButtonPress: {
1853 case QEvent::MouseButtonDblClick: {
1854 flyTo(_event->pos(), _event->button() == Qt::MidButton);
1858 case QEvent::MouseMove: {
1860 if(!lookAround_)
break;
1863 QPoint newpos = QPoint(pos.x() -
glWidth() / 2,
glHeight() / 2 - pos.y());
1866 double x = 2.0 * newpos.x() /
glWidth();
1867 double y = 2.0 * newpos.y() /
glHeight();
1869 double xo = 2.0 * oldpos.x() /
glWidth();
1870 double yo = 2.0 * oldpos.y() /
glHeight();
1872 double diffx = xo - x;
1873 double diffy = yo - y;
1891 case QEvent::MouseButtonRelease: {
1892 lookAround_ =
false;
1907 QPointF f(mapFromScene(QPointF(_event->pos().x(), _event->pos().y())));
1908 QPoint pos(f.x(), f.y());
1910 switch (_event->type()) {
1912 case QEvent::MouseButtonPress: {
1918 GLint x2d = f.x() - scenePos().x();
1919 GLint y2d =
glHeight() - (f.y() - scenePos().y());
1920 glReadPixels (x2d, y2d, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, depth);
1924 if (_event->modifiers() & Qt::ShiftModifier) {
1940 case QEvent::MouseButtonDblClick: {
1941 flyTo(_event->pos(), _event->button() == Qt::MidButton);
1945 case QEvent::MouseMove: {
1946 double factor = 1.0;
1948 if (_event->modifiers() == Qt::ShiftModifier)
1952 if (_event->buttons() & (Qt::LeftButton | Qt::MidButton | Qt::RightButton)) {
1953 QPoint newPoint2D = pos;
1956 bool newPoint_hitSphere =
mapToSphere(newPoint2D, newPoint3D);
1962 if ((_event->buttons() & Qt::LeftButton) && (_event->buttons() & Qt::MidButton)) {
1988 else if ((_event->buttons() & Qt::MidButton) || (!
allowRotation_ && (_event->buttons() & Qt::LeftButton)) ) {
1997 translation =
ACG::Vec3d(value_x * factor, -value_y * factor, 0.0);
2001 GLint x2dEnd = newPoint2D.x() - scenePos().x();
2002 GLint y2dEnd =
glHeight() - (newPoint2D.y() - scenePos().y());
2015 translation = unprojectedEnd - unprojectedStart;
2023 }
else if (
allowRotation_ && (_event->buttons() & Qt::LeftButton)) {
2029 if ((newPoint_hitSphere =
mapToSphere(newPoint2D, newPoint3D))) {
2032 if (fabs(cos_angle) < 1.0) {
2033 angle = acos(cos_angle) * 180.0 / M_PI * factor;
2051 const double dragLength = dragVector.y();
2053 const double angle = -dragLength * factor;
2093 case QEvent::MouseButtonRelease: {
2097 if (isRotating_ && (_event->button() == Qt::LeftButton) && (!(_event->buttons() & Qt::MidButton))
2117 if (_event->modifiers() == Qt::ShiftModifier)
2128 if ( _event->modifiers() & Qt::ControlModifier ) {
2132 double numDegrees = double(_event->angleDelta().y()) / 8.0;
2133 double numSteps = numDegrees / 15.0;
2178 if ( (_v2D.x() >= 0) && (_v2D.x() < (int)
glWidth()) &&
2179 (_v2D.y() >= 0) && (_v2D.y() < (int)
glHeight()) )
2181 double x = (double)(_v2D.x() - ((double)
glWidth() / 2.0)) / (
double)
glWidth();
2182 double y = (double)(((
double)
glHeight() / 2.0) - _v2D.y()) / (
double)
glHeight();
2183 double sinx = sin(M_PI * x * 0.5);
2184 double siny = sin(M_PI * y * 0.5);
2185 double sinx2siny2 = sinx * sinx + siny * siny;
2189 _v3D[2] = sinx2siny2 < 1.0 ? sqrt(1.0 - sinx2siny2) : 0.0;
2208 static int msecs=0, count=0;
2210 msecs += frame_time_;
2211 if (count >= 10 && msecs >= 500) {
2213 sprintf( s,
"%.3f fps", (1000.0 * count / (
float)msecs) );
2214 emit statusMessage(s,2000);
2231 glFrontFace( GL_CCW );
2233 glFrontFace( GL_CW );
2254 void glViewer::snapshot(QImage& _image,
int _width,
int _height,
bool _alpha,
bool _hideCoordsys,
int samples) {
2257 int w = 0, h = 0, bak_w = 0, bak_h = 0, left = 0, bottom = 0;
2264 double aspect = (double)w / (
double)h;
2267 if(_width != 0 || _height != 0) {
2271 _width = (int)((
double)_height * aspect);
2274 _height = (int)((
double)_width / aspect);
2283 aspect = (double)w / (
double)h;
2289 if ( createQFBO(fb,&hnd,w,h,&samples) ){
2299 bool formerCoordsysState =
true;
2304 node = sceneGraphRoot_->
find(
"Core Coordsys Node");
2306 formerCoordsysState = node->
visible();
2309 emit statusMessage(QString(tr(
"Could not find coordsys node, thus it will appear in the snapshot anyway.")));
2315 newBack =
ACG::Vec4f(backColorBak[0], backColorBak[1], backColorBak[2], (_alpha ? 0.0f : 1.0f));
2318 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
2320 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2326 glEnable(GL_MULTISAMPLE);
2332 glDisable(GL_MULTISAMPLE);
2337 int testSamples = -1;
2338 createQFBO(temp, &tempHnd, w, h, &testSamples);
2343 QRect rect(QPoint(0, 0), QSize(w,h));
2345 blitQFBO(temp, rect, fb, rect);
2350 _image = QImage(w,h,QImage::Format_ARGB32);
2351 glReadPixels(0,0,w,h,GL_BGRA,GL_UNSIGNED_INT_8_8_8_8_REV,reinterpret_cast<void*>(_image.bits()));
2352 _image = _image.mirrored(
false,
true);
2365 node = sceneGraphRoot_->
find(
"Core Coordsys Node");
2366 if(node != 0 && formerCoordsysState) {
2377 if(_width != 0 || _height != 0) {
2392 snapshot(image, _width, _height, _alpha, _hideCoordsys, samples);
2398 if (!comments.isEmpty())
2399 image.setText(
"Mesh Comments", comments);
2402 image.setText(
"View", view);
2408 QImageWriter writer(fname);
2411 bool rval = writer.canWrite();
2413 writer.write(image);
2416 emit statusMessage (QString(tr(
"Snapshot: "))+fname,5000);
2418 emit statusMessage (QString(tr(
"Could not save snapshot to ")) + fname + QString(tr(
" Error: ")) + writer.errorString() );
2421 void glViewer::slotHideWheels() {
2438 void glViewer::slotShowWheels() {
2455 bool glViewer::wheelsVisible() {
2478 if (!
initialized_ || !sceneGraphRoot_ || !isVisible ())
2484 size_t targetIdx = 0;
2590 double l, r, t, b, w, h, a, radians, wd2, ndfl, zerop, xrange;
2592 w = double(_viewportWidth);
2593 h = double(_viewportHeight);
2597 radians = fovy * 0.5 / 180.0 * M_PI;
2598 wd2 = _properties.
nearPlane() * tan(radians);
2600 ndfl = _properties.
nearPlane() / zerop ;
2601 xrange = a * wd2 * 2 * zerop / _properties.
nearPlane();
2609 double offset2 = offset * ndfl;
2622 _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)
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
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.
QElapsedTimer lastMoveTime_
mouse interaction position
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 *)
ObjectRange objects(IteratorRestriction _restriction, DataType _dataType)
Iterable object range.
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.
QElapsedTimer clickTime_
mouse interaction position
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
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)