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);
bool cursorPositionValid()
Flag if stereo should be enabled for the current viewer.
virtual void setView(const ACG::GLMatrixd &_modelview, const ACG::GLMatrixd &_inverse_modelview)
set view, used for synchronizing
void releaseGLArea()
undo grabbing GLArea
void set_bounding_box(ACG::Vec3d _min, ACG::Vec3d _max)
virtual void toggleNavigationMode()
toggle navigation mode
void frustum(Scalar left, Scalar right, Scalar bottom, Scalar top, Scalar near_plane, Scalar far_plane)
multiply self with a perspective projection matrix
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.
double nearPlane()
Return distance to near Plane.
void addWheelX(QGraphicsWidget *_item)
Add Wheel Widget to Layout.
virtual void perspectiveProjection()
set perspective view (projectionMode(PERSPECTIVE_PROJECTION))
void signalMouseEventIdentify(QMouseEvent *)
void viewMouseEvent(QMouseEvent *_event)
specialized viewer: hande mouse events
void actionCopyView(const QSize &_windowSize=QSize(-1,-1), const int _splitterWidth=-1, const bool _make_c_string=false)
Vec3d right() const
get right-vector w.r.t. camera coordinates
void grabGLArea()
get all Mouse & Key Events for GlWidget
QMouseEvent clickEvent_
mouse interaction position
void signalMouseEventLight(QMouseEvent *)
const GLMatrixd & inverse_modelview() const
get inverse modelview matrix
static double clip(double _angle)
double sceneRadius()
Get radius of the current scene.
ACG::Vec3d cursorPoint3D()
Flag if stereo should be enabled for the current viewer.
void setPlanes(double _near, double _far)
Set near and far plane at the same time.
ACG::Vec3d trackballCenter()
Get virtual trackball center (rotation center when using mouse)
void moveBack()
First person navigation: Move back.
virtual void home()
go to home pos
void slotAnimation()
mouse interaction position
float startDepth_
mouse interaction depth
void viewUpdated()
This signal is emitted when the scene is repainted due to any event.
pick any of the prior targets (should be implemented for all nodes)
bool fast_pick(const QPoint &_mousePos, ACG::Vec3d &_hitPoint)
double lastRotationAngle_
mouse interaction position
void setProjectionMode(const ProjectionMode _mode)
set mode to either ORTHOGRAPHIC_PROJECTION or PERSPECTIVE_PROJECTION
static GLuint getFramebufferRead()
get current read framebuffer of a target
QFramebufferObject * mouseCache_
Framebuffer object that holds the pick cache.
virtual void setHome()
set home position
QStringList collectObjectComments(bool visibleOnly, bool targetedOnly)
void push_modelview_matrix()
push modelview matrix
void setViewerID(int _viewerID)
Set currently active viewer id.
void slotClickTimeout()
Handle click timeout.
virtual QSize sizeHint() const
reimplemented
void unLockUpdate()
Unlock display locked by updateLock().
void updateCursorPosition(QPointF _scenePos)
will be called from CursorPainter to inform the viewer that the cursor position changed ...
double ortho_width() const
Get width of the gl scene in orthogonal projection mode.
void setCursor(const QCursor &_cursor)
Sets the current used cursor.
void set_twosided_lighting(bool _b)
set whether transparent or solid objects should be drawn
void actionPasteView(QSize *_windowSize=NULL, int *_splitterWidth=NULL)
virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *_event)
handle mouse double click events
NavigationMode navigationMode() const
get current navigation mode
ACG::Vec3d constrainedRotationAxis_
mouse interaction position
const GLMatrixd & projection() const
get projection matrix
ProjectionMode
projection mode
void reset_modelview()
reset modelview matrix (load identity)
void twoSidedLighting(bool _state)
set 2-sided lighting on/off
VectorT< float, 4 > Vec4f
virtual void mousePressEvent(QGraphicsSceneMouseEvent *_event)
handle mouse press events
virtual void orthographicProjection()
set orthographic view (projectionMode(ORTHOGRAPHIC_PROJECTION))
QOpenGLFramebufferObject QFramebufferObject
Framebuffer object that holds the pick cache.
virtual void resizeEvent(QGraphicsSceneResizeEvent *_e)
handle resize events
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *_event)
handle mouse move events
QPoint glMapToGlobal(const QPoint &_pos) const
map glarea coords to global coords
bool allowConstrainedRotation()
mouse interaction position
void translate(double _x, double _y, double _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
translate by (_x, _y, _z)
QSize glSize() const
get size of QGLWIdget
int viewport_width() const
get viewport width
void lookAt(const ACG::Vec3d &_eye, const ACG::Vec3d &_center, const ACG::Vec3d &_up)
Set look at transformation directly.
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.
static GLuint getFramebufferDraw()
get current draw framebuffer of a target
void setValue(const QString &key, const QVariant &value)
Wrapper function which makes it possible to enable Debugging output with -DOPENFLIPPER_SETTINGS_DEBUG...
double wheelZoomFactor()
Zoom factor when using mouse wheel.
void updateProjectionMatrix(double _aspect=0.0)
updates projection matrix
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *_event)
handle mouse release events
void encodeView(QString &_view, const QSize &_windowSize=QSize(-1,-1), const int _toolBarWidth=-1, const bool _make_c_string=false)
void rotate(const ACG::Vec3d &axis, double angle)
rotate the scene (around its center) and update modelview matrix
bool allowRotation_
mouse interaction position
bool updatePickCache_
Should the pick cache be updated.
VectorT< T, 3 > transform_point(const VectorT< T, 3 > &_v) const
transform point (x',y',z',1) = M * (x,y,z,1)
static double deg(double _angle)
maps _angle from radiants to degrees (works also for clip()ped angles)
QTimer * timer_
mouse interaction position
void animation(bool _state)
set 2-sided lighting on/off
void signalMouseEventClick(QMouseEvent *, bool _double)
void signalMakeActive()
make this widget active
void clearBuffers()
clear buffers viewport rectangle
static void blendFuncSeparate(GLenum _srcRGB, GLenum _dstRGB, GLenum _srcAlpha, GLenum _dstAlpha)
replaces glBlendFuncSeparate, supports locking
void push_projection_matrix()
push projection matrix
virtual void setFOVY(double _fovy)
Set fovy.
void snapshotFileType(const QString &_type)
static void bindFramebuffer(GLenum _target, GLuint _framebuffer)
replaces glBindFramebuffer, supports locking
double aspect_ratio() const
Returns the viewer's aspect ratio.
ACG::GLState * glstate_
Gl State.
virtual void paintGL(double _aspect=0.0)
draw the scene. Triggered by updateGL().
void multisampling(bool _state)
set multisampling on/off
static void blendFunc(GLenum _sfactor, GLenum _dfactor)
replaces glBlendFunc, supports locking
bool mapToSphere(const QPoint &_p, ACG::Vec3d &_result) const
virtual trackball: map 2D screen point to unit sphere
void initModelviewMatrix()
initialize modelview matrix to identity
static void unlockBlendFuncSeparate()
unlock blend func
void perspective(double _fovY, double _aspect, double _near_plane, double _far_plane)
perspective projection
virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *_e)
handle mouse press events
virtual void wheelEvent(QGraphicsSceneWheelEvent *_event)
handle mouse wheel events
double trackballRadius()
Get trackball radius (rotation sphere when using mouse)
const QStringList ALL_OBJECTS
Iterable object range.
ACG::Vec3d sceneCenter()
Get current scene center (rendering center)
void handleNormalNavigation(QMouseEvent *_event)
Navigate through scene if normal mode has been selected.
QTime clickTime_
mouse interaction position
void setScenePos(const ACG::Vec3d &_center, double _radius, const bool _resetTrackBall=false)
QPoint lastPoint2D_
mouse interaction position
void signalMouseEvent(QMouseEvent *, const std::string &)
ACG::Vec3d lastRotationAxis_
mouse interaction position
static void enable(GLenum _cap, bool _warnRemoved=true)
replaces glEnable, but supports locking
void set_max_render_passes(const unsigned int _max)
set maximum number of render passes
void ortho(double _left, double _right, double _bottom, double _top, double _near_plane, double _far_plane)
orthographic projection
void analyzeSceneGraph(ACG::SceneGraph::BaseNode *_root, unsigned int &_maxPasses, ACG::Vec3d &_bbmin, ACG::Vec3d &_bbmax)
Analyze the SceneGraph <ACG/Scenegraph/SceneGraphAnalysis.hh>
Vec3d up() const
get up-vector w.r.t. camera coordinates
void signalWheelEvent(QWheelEvent *, const std::string &)
Emitted in Pick mode. Uses pick mode.
Viewer::ViewerProperties * properties()
Returns a pointer to the Viewer Status.
double fovyModifier_
mouse interaction position
virtual bool blendForStencilRefBit(GLuint _refbit, GLenum &_src, GLenum &_dst, ACG::Vec4f &_color)
static void drawBuffer(GLenum _mode)
replaces glDrawBuffer, supports locking
void handleFirstPersonNavigation(QMouseEvent *_event)
Navigate through scene if first person mode has been selected.
QPoint glMapFromGlobal(const QPoint &_pos) const
map global to glarea coords
void resolveStereoAnyglyph(int _viewerID)
Resolve stereo buffers as anaglyph.
void paintCursor(ACG::GLState *_state)
Cursor painting function. The _state has to be setup that 0,0,0 is at the cursor position.
Vec3d unproject(const Vec3d &_winPoint) const
unproject point in window coordinates _winPoint to world coordinates
Vec3d project(const Vec3d &_point) const
project point in world coordinates to window coordinates
ACG::Vec4f backgroundColor()
Get current background color.
VectorT< double, 3 > Vec3d
Viewer::ViewerProperties & properties_
All properties for this viewer.
unsigned int glHeight() const
get height of QGLWidget
ProjectionMode projectionMode() const
get current projection mode
void set_clear_color(const Vec4f &_col)
set background color
virtual void updateGL()
Redraw scene. Triggers paint event for updating the view (cf. drawNow()).
int viewport_height() const
get viewport height
void get_viewport(int &_left, int &_bottom, int &_width, int &_height) const
get viewport
static void shadeModel(GLenum _mode)
replaces glShadeModel, supports locking
void sceneGraph(ACG::SceneGraph::BaseNode *_root, unsigned int _maxPasses, ACG::Vec3d _bbmin, ACG::Vec3d _bbmax, const bool _resetTrackBall=false)
RendererInfo * active(int _id)
Get the current active renderer.
use provided normals as is
ChildIter find(BaseNode *_node)
void objectMarker(ViewObjectMarker *_marker)
set object marker for viewer
Interface to add additional rendering functions from within plugins.
bool initialized_
Have the viewer gl properties been initalized.
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 setCoreProfileMode(bool _enable)
Tell renderer to use core or compatibility profile.
virtual void moveEvent(QGraphicsSceneMoveEvent *_e)
handle move events
void snapshotCounter(const int _counter)
Vec3d viewing_direction() const
get viewing ray
void stereo(bool _stereo)
Flag if stereo should be enabled for the current viewer.
int setupScene(int _viewerID, int _width, int _height, int _samples=0, int _stereoEye=-1)
Bind fbo for scene rendering.
QTime lastMoveTime_
mouse interaction position
virtual bool blendForStencilRefNumber(GLuint _reference, GLenum &_src, GLenum &_dst, ACG::Vec4f &_color)
void viewingDirection(const ACG::Vec3d &_dir, const ACG::Vec3d &_up)
set the viewing direction
double farPlane()
Return distance to far Plane.
QRectF cursorBoundingBox()
Bounding box of the cursor.
Vec3d eye() const
get eye point
bool backFaceCulling()
Get current state of backface culling.
static void lockBlendFuncSeparate(bool _rgb=true, bool _alpha=true)
lock blend func
virtual bool stencilRefForObject(BaseObjectData *_obj, GLuint &_reference)=0
void reset_projection()
reset projection matrix (load identity)
void viewChanged()
This signal is emitted whenever the view is changed by the user.
void show()
Show node: set status to Active.
virtual ~glViewer()
Destructor.
void startDragEvent(QMouseEvent *_event)
const GLMatrixd & modelview() const
get modelview matrix
bool wheelInvert()
Invert mouse wheel direction?
virtual void slotWheelY(double _dAngle)
process signals from wheelX_
int numActive(int _id)
Get the number of active post processors for viewer.
QTimer clickTimer_
mouse interaction position
NavigationMode
Navigation mode.
void drawMode(ACG::SceneGraph::DrawModes::DrawMode _mode)
set draw mode (No test if this mode is available!)
void signalCustomContextMenuRequested(const QPoint &)
Viewer::ActionMode actionMode()
get the action mode
virtual void dropEvent(QGraphicsSceneDragDropEvent *_e)
drag & drop for modelview copying
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
CursorPainter * cursorPainter()
Flag if stereo should be enabled for the current viewer.
void rotate(double _angle, double _x, double _y, double _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
rotate around axis (_x, _y, _z) by _angle
DLLEXPORT ObjectIterator objectsEnd()
Return Iterator to Object End.
static void activeTexture(GLenum _texunit)
replaces glActiveTexture, no locking support
virtual void makeCurrent()
Makes this widget the current widget for OpenGL operations.
void traverse_multipass(BaseNode *_node, Action &_action, const unsigned int &_pass)
void pop_modelview_matrix()
pop modelview matrix
void identity()
setup an identity matrix
void pop_projection_matrix()
pop projection matrix
virtual void slotWheelX(double _dAngle)
process signals from wheelX_
ACG::Vec3d unproject(const ACG::Vec3d &pt)
Framebuffer object that holds the pick cache.
static void bindBuffer(GLenum _target, GLuint _buffer)
replaces glBindBuffer, supports locking
void drawCursor()
draw the cursor
double wheelZoomFactorShift()
Zoom factor when using mouse wheel and pressing shift.
virtual void slotWheelZ(double _dist)
process signals from wheelZ_
void hide()
Hide Node: set status to HideNode.
void setglState(ACG::GLState *_glState)
Pointer to the glState of the Viewer.
bool visible()
Is node visible (status == Active)?
void initialize()
initialize all state variables (called by constructor)
virtual void dragEnterEvent(QGraphicsSceneDragDropEvent *_e)
drag & drop for modelview copying
void setCursorPainter(CursorPainter *_cursorPainter)
sets the current cursor painter
void set_modelview(const GLMatrixd &_m)
set modelview
unsigned int glWidth() const
get width of QGLWidget
void allow_multisampling(bool _b)
Disable multisampling globally.
virtual void snapshot(int _width=0, int _height=0, bool _alpha=false, bool _hideCoordsys=false, int samples=1)
bool enabled()
Returns true if cursor painting is enabled and compatible cursor is set.
virtual void flyTo(const QPoint &_pos, bool _moveBack)
Animated flight to or away from a given point.
bool pick(ACG::SceneGraph::PickTarget _pickTarget, const QPoint &_mousePos, size_t &_nodeIdx, size_t &_targetIdx, ACG::Vec3d *_hitPointPtr=0)
unsigned int activeId(int _id)
Get the id of the active renderer.
void setState()
set the whole stored gl state
void set_msSinceLastRedraw(unsigned int _ms)
set time passed since last redraw in milliseconds
double near_plane() const
Returns a chili cheese burger.
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.
static void disable(GLenum _cap, bool _warnRemoved=true)
replaces glDisable, but supports locking
const DataType DATA_ALL(UINT_MAX)
Identifier for all available objects.
void trackMouse(bool _track)
Enable/disable mouse tracking (move events with no button press)
NormalsMode
Automatically normalize normals?
bool lastPoint_hitSphere_
mouse interaction position
virtual void render(ACG::GLState *_glState, Viewer::ViewerProperties &_properties)
rendering function
double orthoWidth()
Get width of the gl scene in orthogonal projection mode (defaults to 2.0)
VectorT< T, 3 > transform_vector(const VectorT< T, 3 > &_v) const
transform vector (x',y',z',0) = A * (x,y,z,0)
void moveForward()
First person navigation: Move forward.
void lookAt(const Vec3d &_eye, const Vec3d &_center, const Vec3d &_up)
set camera by lookAt
Mark per returned reference bits.
glViewer(QGraphicsScene *_scene, OFGLWidget *_glWidget, Viewer::ViewerProperties &_properties, QGraphicsWidget *_parent=0)
double far_plane() const
Returns a peanut butter sandwich.
void translate(Scalar _x, Scalar _y, Scalar _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply self with translation matrix (x,y,z)
void set_projection(const GLMatrixd &_m)
set projection
virtual void initializeGL()
Return a resonable size hint.
void signalSceneGraphChanged(ACG::SceneGraph::BaseNode *_root)
scene graph has changed
PostProcessing * postproc_
Post-Processing executor.
void setCoordSysProjection(glViewer::ProjectionMode _mode)
helper function for setting the projection mode of the coordinate system node
ACG::Vec3d lastPoint3D_
mouse interaction position
void translate(const ACG::Vec3d &trans)
translate the scene and update modelview matrix
ACG::SceneGraph::BaseNode * getSceneGraphRootNode()
get scenegraph root node
void slotPropertiesUpdated()
std::string pickMode()
get active pick mode
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)
virtual void toggleProjectionMode()
toggle projection mode
int viewerId()
Get the id of the viewer this viewerproperties belongs to.
void strafeLeft()
First person navigation: Strafe left.
virtual void viewAll()
view the whole scene
void viewWheelEvent(QWheelEvent *_event)
specialized viewer: handle wheel events
static void bindTexture(GLenum _target, GLuint _buffer)
replaces glBindTexture, supports locking
NormalsMode normalsMode() const
get treatment of normals
void strafeRight()
First person navigation: Strafe Right.