62 #include <ACG/GL/acg_glew.hh>
64 #include "QtBaseViewer.hh"
65 #include "QtGLViewerLayout.hh"
66 #include "PostProcessing.hh"
68 #include <ACG/QtWidgets/QtWheel.hh>
69 #include <ACG/Scenegraph/CoordsysNode.hh>
71 #include <ACG/GL/GLError.hh>
72 #include <ACG/GL/IRenderer.hh>
74 #include <QGraphicsWidget>
78 #include <QtNetwork/QUdpSocket>
80 #include <QGraphicsSceneDragDropEvent>
81 #include <QPropertyAnimation>
86 #include <QApplication>
88 #include <QColorDialog>
90 #include <QGraphicsView>
91 #include <QGraphicsProxyWidget>
93 #include <QImageWriter>
95 #if QT_VERSION < 0x050000
96 #include <QGLFramebufferObject>
98 #include <QOpenGLFramebufferObject>
110 #include <OpenFlipper/common/ViewObjectMarker.hh>
114 #include <OpenFlipper/common/RendererInfo.hh>
122 static const char COPY_PASTE_VIEW_START_STRING[] =
123 "ACG::QtWidgets::QGLViewerWidget encoded view";
129 QGLWidget* _glWidget,
131 QGraphicsWidget* _parent) :
132 QGraphicsWidget(_parent),
133 glareaGrabbed_(false),
134 projectionUpdateLocked_(false),
136 glWidget_(_glWidget),
138 updatePickCache_(true),
139 pickCacheSupported_(true),
140 constrainedRotationAxis_(
std::numeric_limits<double>::quiet_NaN(), 0, 0),
141 clickEvent_(QEvent::MouseButtonPress, QPoint (),
Qt::NoButton,
Qt::NoButton,
Qt::NoModifier),
142 properties_(_properties),
145 flyAnimationPerspective_(0),
146 flyAnimationOrthogonal_(0),
148 currentAnimationPos_(0.0),
175 QSizePolicy sp = sizePolicy();
176 sp.setHorizontalPolicy( QSizePolicy::Expanding );
177 sp.setVerticalPolicy( QSizePolicy::Expanding );
178 sp.setHorizontalStretch( 1 );
179 sp.setVerticalStretch( 1 );
182 redrawTime_.start ();
185 timer_ =
new QTimer(
this );
199 setAcceptDrops(
true);
230 glWidget_->makeCurrent();
234 glWidget_->swapBuffers();
241 unsigned int _maxPasses,
244 const bool _resetTrackBall)
246 sceneGraphRoot_ = _root;
248 if (sceneGraphRoot_ )
254 if ( ( _bbmin[0] > _bbmax[0] ) ||
255 ( _bbmin[1] > _bbmax[1] ) ||
256 ( _bbmin[2] > _bbmax[2] ) ) {
268 if ( ( _bbmax - _bbmin ).max() <
OpenFlipperSettings().value(
"Core/Gui/glViewer/minimalSceneSize",0.1).toDouble() ) {
275 ( _bbmax - _bbmin ).norm() * 0.5,
298 trackMouse_ = _track;
352 emit projectionModeChanged(
true );
354 emit projectionModeChanged(
false );
375 emit navigationModeChanged(
true );
377 emit navigationModeChanged(
false );
382 if(_fovy <= 0.0 || _fovy >= 180) {
383 std::cerr <<
"Error: Minimum or maximum fovy angle exceeded!" << std::endl;
393 if( projectionUpdateLocked_ )
406 const double fovy = this->field_of_view_vertical();
427 if(_resetTrackBall) {
442 if ( nearPlane <= 0.0 ) {
443 std::cerr <<
"Error in BaseViewer drawScene, nearplane <= 0.0" << std::endl;
444 nearPlane = 0.000000000000001;
448 if ( nearPlane > farPlane ) {
449 std::cerr <<
"Error in BaseViewer setScenePos, Nearplane > Farplane" << std::endl;
450 std::swap(nearPlane,farPlane);
495 switch(normalsMode_ = _mode)
515 unsigned int _l,
unsigned int _t,
516 unsigned int _w,
unsigned int _h,
522 _image = glWidget_->grabFrameBuffer(
true).copy (_l, _t, _w, _h).convertToFormat (QImage::Format_RGB32);
545 void glViewer::drawScene()
564 if ( nearPlane <= 0.0 ) {
565 std::cerr <<
"Error in BaseViewer drawScene, nearplane < 0" << std::endl;
566 nearPlane = 0.000000000000001;
570 if ( nearPlane > farPlane ) {
571 std::cerr <<
"Error in BaseViewer drawScene, Nearplane > Farplane" << std::endl;
572 std::swap(nearPlane,farPlane);
606 GLuint backbufferFbo = 0;
607 GLuint backbufferTarget = 0;
608 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, (GLint*)&backbufferFbo);
609 glGetIntegerv(GL_DRAW_BUFFER, (GLint*)&backbufferTarget);
616 GLint curViewport[4];
617 glGetIntegerv(GL_VIEWPORT, curViewport);
618 glScissor(curViewport[0], curViewport[1], curViewport[2], curViewport[3]);
619 glEnable(GL_SCISSOR_TEST);
620 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
621 glDisable(GL_SCISSOR_TEST);
631 bool stereoOpenGL =
false;
632 bool stereoAnaglyph =
false;
637 stereoOpenGL = OpenFlipper::Options::stereoMode () == OpenFlipper::Options::OpenGL && OpenFlipper::Options::glStereo ();
638 stereoAnaglyph = !stereoOpenGL;
642 if (!stereoOpenGL && !stereoAnaglyph)
660 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) {
678 if (stereoOpenGL && !numPostProcessors) {
680 glDrawBuffer(eye ? GL_BACK_RIGHT : GL_BACK_LEFT);
681 glEnable(GL_SCISSOR_TEST);
682 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
683 glDisable(GL_SCISSOR_TEST);
698 glBindFramebuffer(GL_FRAMEBUFFER, backbufferFbo);
699 glDrawBuffer(backbufferTarget);
725 glDrawBuffer(backbufferTarget);
745 frame_time_ = timer.elapsed();
757 void glViewer::drawScene_mono()
759 if (sceneGraphRoot_) {
762 QSet<GLuint> references;
766 glClear (GL_STENCIL_BUFFER_BIT);
768 glStencilOp (GL_KEEP, GL_KEEP, GL_ZERO);
769 glStencilFunc (GL_ALWAYS, 0, ~0);
781 o_it->stencilRefNode ()->setReference (ref);
782 o_it->stencilRefNode ()->show ();
787 o_it->stencilRefNode ()->hide ();
804 for (
unsigned int i = 0; i <
sizeof (GLuint) * 8; i++)
805 if (refBits & (1 << i))
806 references << (1 << i);
809 glPushAttrib(GL_ALL_ATTRIB_BITS);
816 int vp_l, vp_b, vp_w, vp_h;
819 glMatrixMode(GL_PROJECTION);
822 glOrtho(0, vp_w, vp_h, 0, 0, 1.0);
823 glMatrixMode(GL_MODELVIEW);
827 glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
829 foreach (
unsigned int ref, references)
835 unsigned int mask = ~0;
848 glStencilFunc (GL_EQUAL, ref, mask);
851 glColor4f (color[0], color [1], color [2], color[3]);
856 glVertex2i(vp_w, vp_h);
862 glMatrixMode(GL_PROJECTION);
864 glMatrixMode(GL_MODELVIEW);
928 unsigned int maxPases = 1;
1001 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
1002 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
1003 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
1004 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1005 glPixelStorei(GL_PACK_ROW_LENGTH, 0);
1006 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
1007 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
1008 glPixelStorei(GL_PACK_ALIGNMENT, 1);
1016 if (sceneGraphRoot_)
1018 unsigned int maxPases = 1;
1022 sceneGraph ( sceneGraphRoot_, maxPases,bbmin,bbmax,
true);
1041 glPushAttrib (GL_ALL_ATTRIB_BITS);
1048 glMatrixMode(GL_PROJECTION);
1051 glMatrixMode(GL_MODELVIEW);
1061 glColor4f(1.0,0.0,0.0,1.0);
1072 glMatrixMode(GL_PROJECTION);
1088 scene()->height () - scenePos().y() - size().height (),
1089 size().width (), size().height (),
1090 scene()->width (), scene()->height ());
1099 scene()->height () - scenePos().y() - size().height (),
1100 size().width (), size().height (),
1101 scene()->width (), scene()->height ());
1110 const int _splitterWidth ,
const bool _make_c_string )
1116 static const char *line_delim_c =
" \\\n";
1117 static const char *line_delim_std = line_delim_c + 2;
1118 const char *line_delim = _make_c_string ? line_delim_c : line_delim_std;
1124 _view += QString(COPY_PASTE_VIEW_START_STRING) + line_delim;
1125 _view += QString::number(m(0,0)) +
" " + QString::number(m(0,1)) +
" " + QString::number(m(0,2)) +
" " + QString::number(m(0,3)) + line_delim;
1126 _view += QString::number(m(1,0)) +
" " + QString::number(m(1,1)) +
" " + QString::number(m(1,2)) +
" " + QString::number(m(1,3)) + line_delim;
1127 _view += QString::number(m(2,0)) +
" " + QString::number(m(2,1)) +
" " + QString::number(m(2,2)) +
" " + QString::number(m(2,3)) + line_delim;
1128 _view += QString::number(m(3,0)) +
" " + QString::number(m(3,1)) +
" " + QString::number(m(3,2)) +
" " + QString::number(m(3,3)) + line_delim;
1131 _view += QString::number(p(0,0)) +
" " + QString::number(p(0,1)) +
" " + QString::number(p(0,2)) +
" " + QString::number(p(0,3)) + line_delim;
1132 _view += QString::number(p(1,0)) +
" " + QString::number(p(1,1)) +
" " + QString::number(p(1,2)) +
" " + QString::number(p(1,3)) + line_delim;
1133 _view += QString::number(p(2,0)) +
" " + QString::number(p(2,1)) +
" " + QString::number(p(2,2)) +
" " + QString::number(p(2,3)) + line_delim;
1134 _view += QString::number(p(3,0)) +
" " + QString::number(p(3,1)) +
" " + QString::number(p(3,2)) +
" " + QString::number(p(3,3)) + line_delim;
1137 _view += QString::number(_windowSize.width()) +
" " + QString::number(_windowSize.height()) +
" " + QString::number(_splitterWidth)+
" " + QString::number(projectionMode_) +
" " + QString::number(
properties_.
orthoWidth()) + line_delim;;
1140 _view += QString::fromUtf8(
"%1 %2").arg(size().width()).arg(size().height());
1154 QSize *_windowSize ,
1155 int* _splitterWidth , QSize *_viewportSize)
1158 QString temp = _view;
1159 temp.remove(0,
sizeof(COPY_PASTE_VIEW_START_STRING));
1162 QStringList split = temp.split(QRegExp(
"[\\n\\s]"),QString::SkipEmptyParts);
1165 if ( split.size() >= 37 ) {
1171 for (std::size_t i = 0; i < 4; ++i)
1173 for (std::size_t j = 0; j < 4; ++j)
1175 m(i,j) = split[i*4 + j].toDouble();
1176 p(i,j) = split[i*4 + j +16].toDouble();
1186 int w = split[32].toInt();
1187 int h = split[33].toInt();
1188 *_windowSize = QSize(w,h);
1194 if (_splitterWidth) {
1195 *_splitterWidth = split[34].toInt();
1201 pMode = split[35].toInt();
1202 ortho_width = split[36].toDouble();
1204 if (_viewportSize && split.size() >= 39) {
1205 *_viewportSize = QSize(split[37].toInt(), split[38].toInt());
1208 }
else if ( split.size() == 36 ) {
1214 for (std::size_t i = 0; i < 4; ++i)
1216 for (std::size_t j = 0; j < 4; ++j)
1218 m(i,j) = split[i*4 + j].toDouble();
1219 p(i,j) = split[i*4 + j +16].toDouble();
1229 int w = split[32].toInt();
1230 int h = split[33].toInt();
1231 *_windowSize = QSize(w,h);
1238 if (_splitterWidth) {
1239 *_splitterWidth = -1;
1245 pMode = split[34].toInt();
1246 ortho_width = split[35].toDouble();
1249 std::cerr <<
"Unable to paste view ... wrong parameter count!! is" << split.size() << std::endl;
1257 int* _splitterWidth , QSize *_viewportSize)
1259 if (_view.left(
sizeof(COPY_PASTE_VIEW_START_STRING)-1) != QString(COPY_PASTE_VIEW_START_STRING))
1261 std::cerr <<
"No View was copied." << std::endl;
1269 if (!
decodeView(_view, m, p, pMode, ortho_width,
1270 _windowSize, _splitterWidth, _viewportSize))
1294 const bool _make_c_string )
1297 encodeView(view,_windowSize,_splitterWidth, _make_c_string);
1298 QApplication::clipboard()->setText(view);
1308 view = QApplication::clipboard()->text();
1312 void glViewer::actionSetView(QString view) {
1319 glViewer::createWidgets()
1324 wheelZ_->setMinimumSize(wheelZ_->
sizeHint());
1325 wheelZ_->setMaximumSize(wheelZ_->
sizeHint());
1326 connect(wheelZ_,SIGNAL(angleChangedBy(
double)),
1328 wheelZ_->setToolTip( tr(
"Translate along <b>z-axis</b>."));
1329 wheelZ_->setWhatsThis( tr(
"Translate along <b>z-axis</b>."));
1332 wheelY_->setMinimumSize(wheelY_->
sizeHint());
1333 wheelY_->setMaximumSize(wheelY_->
sizeHint());
1334 connect(wheelY_,SIGNAL(angleChangedBy(
double)),
1336 wheelY_->setToolTip(tr(
"Rotate around <b>y-axis</b>."));
1337 wheelY_->setWhatsThis( tr(
"Rotate around <b>y-axis</b>."));
1340 wheelX_->setMinimumSize(wheelX_->
sizeHint());
1341 wheelX_->setMaximumSize(wheelX_->
sizeHint());
1342 connect(wheelX_,SIGNAL(angleChangedBy(
double)),
1344 wheelX_->setToolTip(tr(
"Rotate around <b>x-axis</b>."));
1345 wheelX_->setWhatsThis( tr(
"Rotate around <b>x-axis</b>."));
1351 QGraphicsWidget *wheelX = glScene_->addWidget (wheelX_);
1352 QGraphicsWidget *wheelY = glScene_->addWidget (wheelY_);
1353 QGraphicsWidget *wheelZ = glScene_->addWidget (wheelZ_);
1355 wheelX_->setWindowOpacity (0.5);
1356 wheelY_->setWindowOpacity (0.5);
1357 wheelZ_->setWindowOpacity (0.5);
1359 wheelX->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
1360 wheelY->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
1361 wheelZ->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
1365 glBaseLayout_->addWheelY(wheelY);
1366 glBaseLayout_->addWheelZ(wheelZ);
1368 connect(wheelX_,SIGNAL(hideWheel()),
this,SLOT(slotHideWheels()));
1369 connect(wheelY_,SIGNAL(hideWheel()),
this,SLOT(slotHideWheels()));
1370 connect(wheelZ_,SIGNAL(hideWheel()),
this,SLOT(slotHideWheels()));
1372 setLayout(glBaseLayout_);
1409 glstate_->
rotate(_angle, _axis[0], _axis[1], _axis[2], ACG::MULT_FROM_LEFT);
1422 return size().width();
1425 return size().height();
1428 return QSize(size().width(),size().height());
1431 QPoint p (scene()->views().front()->mapFromGlobal(_pos));
1432 QPointF f (mapFromScene(QPointF(p.x(), p.y ())));
1433 return QPoint (f.x(), f.y());
1437 QPointF f (mapToScene(QPointF(_pos.x(), _pos.y ())));
1438 QPoint p (f.x(), f.y());
1439 return scene()->views().front()->mapToGlobal(p);
1442 double glViewer::field_of_view_vertical()
const {
1481 glareaGrabbed_ =
true;
1485 std::cerr <<
"grabGLArea: Blanking cursorpainter cursor" << std::endl;
1487 setCursor(Qt::BlankCursor);
1488 std::cerr <<
"grabGLArea: Blanking qt cursor" << std::endl;
1496 glareaGrabbed_ =
false;
1503 std::cerr <<
"grabGLArea: Setting cursorPainter cursor to arrow" << std::endl;
1505 setCursor(Qt::ArrowCursor);
1506 std::cerr <<
"grabGLArea: Setting qt cursor to arrow" << std::endl;
1517 glScene_->update ();
1519 QPoint p (_e->pos().x(), _e->pos().y());
1528 QPoint p (_e->scenePos().x(), _e->scenePos().y());
1529 QMouseEvent me(QEvent::MouseButtonPress ,p, _e->screenPos(), _e->button(),
1530 _e->buttons(), _e->modifiers());
1534 glScene_->update ();
1541 case Viewer::ExamineMode:
1542 if ((_e->modifiers() & Qt::ControlModifier))
1559 case Viewer::LightMode:
1563 case Viewer::PickingMode:
1568 case Viewer::QuestionMode:
1581 QPoint p (_e->scenePos().x(), _e->scenePos().y());
1582 QMouseEvent me(QEvent::MouseButtonDblClick ,p, _e->screenPos(), _e->button(),
1583 _e->buttons(), _e->modifiers());
1587 glScene_->update ();
1591 case Viewer::ExamineMode:
1596 case Viewer::LightMode:
1600 case Viewer::PickingMode:
1605 case Viewer::QuestionMode:
1617 QPoint p (_e->scenePos().x(), _e->scenePos().y());
1618 QMouseEvent me(QEvent::MouseMove ,p, _e->screenPos(), _e->button(),
1619 _e->buttons(), _e->modifiers());
1624 case Viewer::ExamineMode:
1628 case Viewer::LightMode:
1632 case Viewer::PickingMode:
1635 if ((_e->buttons() & (Qt::LeftButton | Qt::MidButton | Qt::RightButton))
1643 case Viewer::QuestionMode:
1657 QPoint p (_e->scenePos().x(), _e->scenePos().y());
1658 QMouseEvent me(QEvent::MouseButtonRelease ,p, _e->screenPos(), _e->button(),
1659 _e->buttons(), _e->modifiers());
1669 case Viewer::ExamineMode:
1677 if (abs (diff.x ()) <= 1 && abs (diff.y ()) <= 1 && elapsed <= QApplication::doubleClickInterval () / 2)
1680 clickTimer_.setInterval (QApplication::doubleClickInterval () - elapsed);
1691 case Viewer::LightMode:
1695 case Viewer::PickingMode:
1700 case Viewer::QuestionMode:
1709 isRotating_ =
false;
1718 QPoint p (_e->scenePos().x(), _e->scenePos().y());
1719 QWheelEvent we(p, _e->screenPos(), _e->delta(), _e->buttons(),
1720 _e->modifiers(), _e->orientation());
1725 case Viewer::ExamineMode:
1729 case Viewer::PickingMode:
1737 isRotating_ =
false;
1744 std::cerr <<
"dragEnter" << std::endl;
1746 QPoint p (_e->pos().x(), _e->pos().y());
1747 QDragEnterEvent de(p, _e->possibleActions(), _e->mimeData(), _e->buttons(),
1758 std::cerr <<
"drop" << std::endl;
1760 QPoint p (_e->pos().x(), _e->pos().y());
1761 QDropEvent de(p, _e->possibleActions(), _e->mimeData(), _e->buttons(),
1788 QPointF f(mapFromScene(QPointF(_event->pos().x(), _event->pos().y())));
1789 QPoint pos(f.x(), f.y());
1791 switch (_event->type()) {
1793 case QEvent::MouseButtonPress: {
1799 case QEvent::MouseButtonDblClick: {
1800 flyTo(_event->pos(), _event->button() == Qt::MidButton);
1804 case QEvent::MouseMove: {
1806 if(!lookAround_)
break;
1809 QPoint newpos = QPoint(pos.x() -
glWidth() / 2,
glHeight() / 2 - pos.y());
1812 double x = 2.0 * newpos.x() /
glWidth();
1813 double y = 2.0 * newpos.y() /
glHeight();
1815 double xo = 2.0 * oldpos.x() /
glWidth();
1816 double yo = 2.0 * oldpos.y() /
glHeight();
1818 double diffx = xo - x;
1819 double diffy = yo - y;
1837 case QEvent::MouseButtonRelease: {
1838 lookAround_ =
false;
1852 QPointF f(mapFromScene(QPointF(_event->pos().x(), _event->pos().y())));
1853 QPoint pos(f.x(), f.y());
1855 switch (_event->type()) {
1857 case QEvent::MouseButtonPress: {
1863 GLint x2d = f.x() - scenePos().x();
1864 GLint y2d =
glHeight() - (f.y() - scenePos().y());
1865 glReadPixels (x2d, y2d, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, depth);
1869 if (_event->modifiers() & Qt::ShiftModifier) {
1885 case QEvent::MouseButtonDblClick: {
1886 flyTo(_event->pos(), _event->button() == Qt::MidButton);
1890 case QEvent::MouseMove: {
1891 double factor = 1.0;
1893 if (_event->modifiers() == Qt::ShiftModifier)
1897 if (_event->buttons() & (Qt::LeftButton | Qt::MidButton | Qt::RightButton)) {
1898 QPoint newPoint2D = pos;
1901 bool newPoint_hitSphere =
mapToSphere(newPoint2D, newPoint3D);
1907 if ((_event->buttons() & Qt::LeftButton) && (_event->buttons() & Qt::MidButton)) {
1933 else if ((_event->buttons() & Qt::MidButton) || (!
allowRotation_ && (_event->buttons() & Qt::LeftButton)) ) {
1942 translation =
ACG::Vec3d(value_x * factor, -value_y * factor, 0.0);
1946 GLint x2dEnd = newPoint2D.x() - scenePos().x();
1947 GLint y2dEnd =
glHeight() - (newPoint2D.y() - scenePos().y());
1960 translation = unprojectedEnd - unprojectedStart;
1968 }
else if (
allowRotation_ && (_event->buttons() & Qt::LeftButton)) {
1974 if ((newPoint_hitSphere =
mapToSphere(newPoint2D, newPoint3D))) {
1977 if (fabs(cos_angle) < 1.0) {
1978 angle = acos(cos_angle) * 180.0 / M_PI * factor;
1996 const double dragLength = dragVector.y();
1998 const double angle = -dragLength * factor;
2038 case QEvent::MouseButtonRelease: {
2042 if (isRotating_ && (_event->button() == Qt::LeftButton) && (!(_event->buttons() & Qt::MidButton))
2062 if (_event->modifiers() == Qt::ShiftModifier)
2073 if ( _event->modifiers() & Qt::ControlModifier ) {
2077 double numDegrees = double(_event->delta()) / 8.0;
2078 double numSteps = numDegrees / 15.0;
2123 if ( (_v2D.x() >= 0) && (_v2D.x() < (int)
glWidth()) &&
2124 (_v2D.y() >= 0) && (_v2D.y() < (int)
glHeight()) )
2126 double x = (double)(_v2D.x() - ((double)
glWidth() / 2.0)) / (
double)
glWidth();
2127 double y = (double)(((
double)
glHeight() / 2.0) - _v2D.y()) / (
double)
glHeight();
2128 double sinx = sin(M_PI * x * 0.5);
2129 double siny = sin(M_PI * y * 0.5);
2130 double sinx2siny2 = sinx * sinx + siny * siny;
2134 _v3D[2] = sinx2siny2 < 1.0 ? sqrt(1.0 - sinx2siny2) : 0.0;
2153 static int msecs=0, count=0;
2155 msecs += frame_time_;
2156 if (count >= 10 && msecs >= 500) {
2158 sprintf( s,
"%.3f fps", (1000.0 * count / (
float)msecs) );
2159 emit statusMessage(s,2000);
2176 glFrontFace( GL_CCW );
2178 glFrontFace( GL_CW );
2199 void glViewer::snapshot(QImage& _image,
int _width,
int _height,
bool _alpha,
bool _hideCoordsys,
int samples) {
2201 int w = 0, h = 0, bak_w = 0, bak_h = 0, left = 0, bottom = 0;
2210 if(_width != 0 || _height != 0) {
2214 double aspect = (double)w / (
double)h;
2215 _width = (int)((
double)_height * aspect);
2218 double aspect = (double)w / (
double)h;
2219 _height = (int)((
double)_width / aspect);
2231 format.setInternalTextureFormat(GL_RGBA);
2232 format.setTextureTarget(GL_TEXTURE_2D);
2234 format.setAttachment(QFramebufferObject::CombinedDepthStencil);
2238 format.setSamples(samples);
2243 if ( fb.isValid() ){
2253 bool formerCoordsysState =
true;
2258 node = sceneGraphRoot_->
find(
"Core Coordsys Node");
2260 formerCoordsysState = node->
visible();
2263 emit statusMessage(QString(tr(
"Could not find coordsys node, thus it will appear in the snapshot anyway.")));
2269 newBack =
ACG::Vec4f(backColorBak[0], backColorBak[1], backColorBak[2], (_alpha ? 0.0f : 1.0f));
2272 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
2274 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2280 glEnable(GL_MULTISAMPLE);
2286 glDisable(GL_MULTISAMPLE);
2290 tempFormat.setInternalTextureFormat(GL_RGBA);
2291 tempFormat.setTextureTarget(GL_TEXTURE_2D);
2293 if (format.samples() != 0)
2297 QRect rect(QPoint(0, 0), QSize(w,h));
2299 QFramebufferObject::blitFramebuffer(&temp, rect, &fb, rect);
2304 _image = QImage(w,h,QImage::Format_ARGB32);
2305 glReadPixels(0,0,w,h,GL_BGRA,GL_UNSIGNED_INT_8_8_8_8_REV,reinterpret_cast<void*>(_image.bits()));
2306 _image = _image.mirrored(
false,
true);
2319 node = sceneGraphRoot_->
find(
"Core Coordsys Node");
2320 if(node != 0 && formerCoordsysState) {
2328 if(_width != 0 || _height != 0) {
2343 snapshot(image, _width, _height, _alpha, _hideCoordsys, samples);
2349 if (!comments.isEmpty())
2350 image.setText(
"Mesh Comments", comments);
2353 image.setText(
"View", view);
2359 QImageWriter writer(fname);
2362 bool rval = writer.canWrite();
2364 writer.write(image);
2367 emit statusMessage (QString(tr(
"Snapshot: "))+fname,5000);
2369 emit statusMessage (QString(tr(
"Could not save snapshot to ")) + fname + QString(tr(
" Error: ")) + writer.errorString() );
2372 void glViewer::slotHideWheels() {
2389 void glViewer::slotShowWheels() {
2406 bool glViewer::wheelsVisible() {
2429 if (!
initialized_ || !sceneGraphRoot_ || !isVisible ())
2434 unsigned int nodeIdx = 0;
2435 unsigned int targetIdx = 0;
2541 double l, r, t, b, w, h, a, radians, wd2, ndfl, zerop, xrange;
2543 w = double(_viewportWidth);
2544 h = double(_viewportHeight);
2548 radians = fovy * 0.5 / 180.0 * M_PI;
2549 wd2 = _properties.
nearPlane() * tan(radians);
2551 ndfl = _properties.
nearPlane() / zerop ;
2552 xrange = a * wd2 * 2 * zerop / _properties.
nearPlane();
2560 double offset2 = offset * ndfl;
2573 _outRight->
translate(-offset, 0.0, 0.0);
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.
void signalMouseEventLight(QMouseEvent *)
void moveForward()
First person navigation: Move forward.
static void bindFramebuffer(GLenum _target, GLuint _framebuffer)
replaces glBindFramebuffer, supports locking
Vec3d right() const
get right-vector w.r.t. camera coordinates
virtual bool blendForStencilRefBit(GLuint _refbit, GLenum &_src, GLenum &_dst, ACG::Vec4f &_color)
PostProcessing * postproc_
Post-Processing executor.
void slotAnimation()
mouse interaction position
void lookAt(const Vec3d &_eye, const Vec3d &_center, const Vec3d &_up)
set camera by lookAt
static void enable(GLenum _cap)
replaces glEnable, but supports locking
void slotPropertiesUpdated()
double sceneRadius()
Get radius of the current scene.
const QStringList ALL_OBJECTS
Iterable object range.
bool initialized_
Have the viewer gl properties been initalized.
bool visible()
Is node visible (status == Active)?
static void bindBuffer(GLenum _target, GLuint _buffer)
replaces glBindBuffer, supports locking
ACG::Vec3d lastRotationAxis_
mouse interaction position
virtual void dragEnterEvent(QGraphicsSceneDragDropEvent *_e)
drag & drop for modelview copying
ACG::Vec3d lastPoint3D_
mouse interaction position
void setCursorPainter(CursorPainter *_cursorPainter)
sets the current cursor painter
Interface to add additional rendering functions from within plugins.
void initialize()
initialize all state variables (called by constructor)
virtual void slotWheelY(double _dAngle)
process signals from wheelX_
void addWheelX(QGraphicsWidget *_item)
Add Wheel Widget to Layout.
double nearPlane()
Return distance to near Plane.
void startDragEvent(QMouseEvent *_event)
void setProjectionMode(const ProjectionMode _mode)
set mode to either ORTHOGRAPHIC_PROJECTION or PERSPECTIVE_PROJECTION
virtual void snapshot(int _width=0, int _height=0, bool _alpha=false, bool _hideCoordsys=false, int samples=1)
virtual void flyTo(const QPoint &_pos, bool _moveBack)
Animated flight to or away from a given point.
virtual void toggleProjectionMode()
toggle projection mode
void twoSidedLighting(bool _state)
set 2-sided lighting on/off
void releaseGLArea()
undo grabbing GLArea
double farPlane()
Return distance to far Plane.
NavigationMode
Navigation mode.
pick any of the prior targets (should be implemented for all nodes)
virtual void toggleNavigationMode()
toggle navigation mode
virtual void viewAll()
view the whole scene
virtual bool stencilRefForObject(BaseObjectData *_obj, GLuint &_reference)=0
static void blendFuncSeparate(GLenum _srcRGB, GLenum _dstRGB, GLenum _srcAlpha, GLenum _dstAlpha)
replaces glBlendFuncSeparate, supports locking
virtual void moveEvent(QGraphicsSceneMoveEvent *_e)
handle move events
void translate(double _x, double _y, double _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
translate by (_x, _y, _z)
Vec3d unproject(const Vec3d &_winPoint) const
unproject point in window coordinates _winPoint to world coordinates
QPoint lastPoint2D_
mouse interaction position
static void bindTexture(GLenum _target, GLuint _buffer)
replaces glBindTexture, supports locking
void resolveStereoAnyglyph(int _viewerID)
Resolve stereo buffers as anaglyph.
virtual void setView(const ACG::GLMatrixd &_modelview, const ACG::GLMatrixd &_inverse_modelview)
set view, used for synchronizing
double lastRotationAngle_
mouse interaction position
CursorPainter * cursorPainter()
Flag if stereo should be enabled for the current viewer.
void signalMouseEventIdentify(QMouseEvent *)
virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *_e)
handle mouse press events
double wheelZoomFactor()
Zoom factor when using mouse wheel.
RendererInfo * active(int _id)
Get the current active renderer.
void strafeLeft()
First person navigation: Strafe left.
double trackballRadius()
Get trackball radius (rotation sphere when using mouse)
QRectF cursorBoundingBox()
Bounding box of the cursor.
void rotate(double _angle, double _x, double _y, double _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
rotate around axis (_x, _y, _z) by _angle
void set_bounding_box(ACG::Vec3d _min, ACG::Vec3d _max)
void translate(const ACG::Vec3d &trans)
translate the scene and update modelview matrix
bool enabled()
Returns true if cursor painting is enabled and compatible cursor is set.
ACG::Vec3d sceneCenter()
Get current scene center (rendering center)
virtual void updateGL()
Redraw scene. Triggers paint event for updating the view (cf. drawNow()).
VectorT< float, 4 > Vec4f
virtual QSize sizeHint() const
reimplemented
void updateProjectionMatrix()
updates projection matrix
QGLFramebufferObjectFormat QFramebufferObjectFormat
Framebuffer object that holds the pick cache.
ACG::Vec3d cursorPoint3D()
Flag if stereo should be enabled for the current viewer.
VectorT< double, 3 > Vec3d
void drawMode(ACG::SceneGraph::DrawModes::DrawMode _mode)
set draw mode (No test if this mode is available!)
const GLMatrixd & modelview() const
get modelview matrix
ProjectionMode projectionMode() const
get current projection mode
NavigationMode navigationMode() const
get current navigation mode
void strafeRight()
First person navigation: Strafe Right.
void traverse_multipass(BaseNode *_node, Action &_action, const unsigned int &_pass)
const GLMatrixd & projection() const
get projection matrix
VectorT< T, 3 > transform_vector(const VectorT< T, 3 > &_v) const
transform vector (x',y',z',0) = A * (x,y,z,0)
virtual void resizeEvent(QGraphicsSceneResizeEvent *_e)
handle resize events
ACG::SceneGraph::BaseNode * getSceneGraphRootNode()
get scenegraph root node
double far_plane() const
Returns a peanut butter sandwich.
virtual void slotWheelZ(double _dist)
process signals from wheelZ_
void show()
Show node: set status to Active.
ACG::Vec3d unproject(const ACG::Vec3d &pt)
Framebuffer object that holds the pick cache.
void setViewerID(int _viewerID)
Set currently active viewer id.
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 slotClickTimeout()
Handle click timeout.
virtual bool blendForStencilRefNumber(GLuint _reference, GLenum &_src, GLenum &_dst, ACG::Vec4f &_color)
void clearBuffers()
clear buffers viewport rectangle
QStringList collectObjectComments(bool visibleOnly, bool targetedOnly)
void snapshotFileType(const QString &_type)
virtual void paintGL()
draw the scene. Triggered by updateGL().
void updateCursorPosition(QPointF _scenePos)
will be called from CursorPainter to inform the viewer that the cursor position changed ...
unsigned int glWidth() const
get width of QGLWidget
virtual void setFOVY(double _fovy)
Set fovy.
static void unlockBlendFuncSeparate()
unlock blend func
void signalWheelEvent(QWheelEvent *, const std::string &)
Emitted in Pick mode. Uses pick mode.
virtual ~glViewer()
Destructor.
void objectMarker(ViewObjectMarker *_marker)
set object marker for viewer
void push_modelview_matrix()
push modelview matrix
static void activeTexture(GLenum _texunit)
replaces glActiveTexture, no locking support
QTimer clickTimer_
mouse interaction position
virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *_event)
handle mouse double click events
int numActive(int _id)
Get the number of active post processors for viewer.
static void drawBuffer(GLenum _mode)
replaces glDrawBuffer, supports locking
void translate(Scalar _x, Scalar _y, Scalar _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply self with translation matrix (x,y,z)
bool wheelInvert()
Invert mouse wheel direction?
void set_max_render_passes(const unsigned int _max)
set maximum number of render passes
void reset_modelview()
reset modelview matrix (load identity)
void pop_projection_matrix()
pop projection matrix
void reset_projection()
reset projection matrix (load identity)
static void shadeModel(GLenum _mode)
replaces glShadeModel, supports locking
int viewport_width() const
get viewport width
bool pick(ACG::SceneGraph::PickTarget _pickTarget, const QPoint &_mousePos, unsigned int &_nodeIdx, unsigned int &_targetIdx, ACG::Vec3d *_hitPointPtr=0)
static void lockBlendFuncSeparate(bool _rgb=true, bool _alpha=true)
lock blend func
static void blendFunc(GLenum _sfactor, GLenum _dfactor)
replaces glBlendFunc, supports locking
virtual void perspectiveProjection()
set perspective view (projectionMode(PERSPECTIVE_PROJECTION))
virtual void render(ACG::GLState *_glState, Viewer::ViewerProperties &_properties)
rendering function
bool mapToSphere(const QPoint &_p, ACG::Vec3d &_result) const
virtual trackball: map 2D screen point to unit sphere
glViewer(QGraphicsScene *_scene, QGLWidget *_glWidget, Viewer::ViewerProperties &_properties, QGraphicsWidget *_parent=0)
const GLMatrixd & inverse_modelview() const
get inverse modelview matrix
QGLFramebufferObject QFramebufferObject
Framebuffer object that holds the pick cache.
void set_twosided_lighting(bool _b)
set whether transparent or solid objects should be drawn
void signalMakeActive()
make this widget active
Mark per returned reference bits.
void actionCopyView(const QSize &_windowSize=QSize(-1,-1), const int _splitterWidth=-1, const bool _make_c_string=false)
DLLEXPORT ObjectIterator objectsEnd()
Return Iterator to Object End.
QPoint glMapToGlobal(const QPoint &_pos) const
map glarea coords to global coords
virtual void home()
go to home pos
void multisampling(bool _state)
set multisampling on/off
int viewerId()
Get the id of the viewer this viewerproperties belongs to.
void snapshotCounter(const int _counter)
void signalMouseEventClick(QMouseEvent *, bool _double)
void paintCursor(ACG::GLState *_state)
Cursor painting function. The _state has to be setup that 0,0,0 is at the cursor position.
virtual void makeCurrent()
Makes this widget the current widget for OpenGL operations.
ACG::Vec3d constrainedRotationAxis_
mouse interaction position
bool fast_pick(const QPoint &_mousePos, ACG::Vec3d &_hitPoint)
virtual void orthographicProjection()
set orthographic view (projectionMode(ORTHOGRAPHIC_PROJECTION))
Vec3d up() const
get up-vector w.r.t. camera coordinates
void analyzeSceneGraph(ACG::SceneGraph::BaseNode *_root, unsigned int &_maxPasses, ACG::Vec3d &_bbmin, ACG::Vec3d &_bbmax)
void ortho(double _left, double _right, double _bottom, double _top, double _near_plane, double _far_plane)
orthographic projection
void signalCustomContextMenuRequested(const QPoint &)
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *_event)
handle mouse move events
unsigned int activeId(int _id)
Get the id of the active renderer.
NormalsMode normalsMode() const
get treatment of normals
NormalsMode
Automatically normalize normals?
void signalMouseEvent(QMouseEvent *, const std::string &)
void frustum(Scalar left, Scalar right, Scalar bottom, Scalar top, Scalar near_plane, Scalar far_plane)
multiply self with a perspective projection matrix
void pop_modelview_matrix()
pop modelview matrix
void hide()
Hide Node: set status to HideNode.
const DataType DATA_ALL(UINT_MAX)
Identifier for all available objects.
bool lastPoint_hitSphere_
mouse interaction position
QMouseEvent clickEvent_
mouse interaction position
Viewer::ActionMode actionMode()
get the action mode
void encodeView(QString &_view, const QSize &_windowSize=QSize(-1,-1), const int _toolBarWidth=-1, const bool _make_c_string=false)
QTime lastMoveTime_
mouse interaction position
Vec3d viewing_direction() const
get viewing ray
ProjectionMode
projection mode
void setCoordSysProjection(glViewer::ProjectionMode _mode)
helper function for setting the projection mode of the coordinate system node
bool backFaceCulling()
Get current state of backface culling.
void viewMouseEvent(QMouseEvent *_event)
specialized viewer: hande mouse events
void stereo(bool _stereo)
Flag if stereo should be enabled for the current viewer.
double orthoWidth()
Get width of the gl scene in orthogonal projection mode (defaults to 2.0)
ACG::GLState * glstate_
Gl State.
virtual void dropEvent(QGraphicsSceneDragDropEvent *_e)
drag & drop for modelview copying
void get_viewport(int &_left, int &_bottom, int &_width, int &_height) const
get viewport
void trackMouse(bool _track)
Enable/disable mouse tracking (move events with no button press)
void setglState(ACG::GLState *_glState)
Pointer to the glState of the Viewer.
double aspect_ratio() const
Returns the viewer's aspect ratio.
void sceneGraph(ACG::SceneGraph::BaseNode *_root, unsigned int _maxPasses, ACG::Vec3d _bbmin, ACG::Vec3d _bbmax, const bool _resetTrackBall=false)
void setState()
set the whole stored gl state
void identity()
setup an identity matrix
float startDepth_
mouse interaction depth
bool allowConstrainedRotation()
mouse interaction position
VectorT< T, 3 > transform_point(const VectorT< T, 3 > &_v) const
transform point (x',y',z',1) = M * (x,y,z,1)
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
void animation(bool _state)
set 2-sided lighting on/off
QPoint glMapFromGlobal(const QPoint &_pos) const
map global to glarea coords
static void disable(GLenum _cap)
replaces glDisable, but supports locking
double near_plane() const
Returns a chili cheese burger.
void setPlanes(double _near, double _far)
Set near and far plane at the same time.
virtual void initializeGL()
Return a resonable size hint.
static double deg(double _angle)
maps _angle from radiants to degrees (works also for clip()ped angles)
Viewer::ViewerProperties * properties()
Returns a pointer to the Viewer Status.
QTimer * timer_
mouse interaction position
void signalSceneGraphChanged(ACG::SceneGraph::BaseNode *_root)
scene graph has changed
virtual void swapBuffers()
Swaps the screen contents with the off-screen buffer.
bool updatePickCache_
Should the pick cache be updated.
void rotate(const ACG::Vec3d &axis, double angle)
rotate the scene (around its center) and update modelview matrix
void set_modelview(const GLMatrixd &_m)
set modelview
bool allowRotation_
mouse interaction position
unsigned int glHeight() const
get height of QGLWidget
void handleNormalNavigation(QMouseEvent *_event)
Navigate through scene if normal mode has been selected.
void moveBack()
First person navigation: Move back.
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 perspective(double _fovY, double _aspect, double _near_plane, double _far_plane)
perspective projection
virtual void slotWheelX(double _dAngle)
process signals from wheelX_
void copyToImage(QImage &_image, GLenum _buffer=GL_BACK)
copy current framebuffer to an QImage
void set_msSinceLastRedraw(unsigned int _ms)
set time passed since last redraw in milliseconds
void handleFirstPersonNavigation(QMouseEvent *_event)
Navigate through scene if first person mode has been selected.
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)
void unLockUpdate()
Unlock display locked by updateLock().
void setValue(const QString &key, const QVariant &value)
Wrapper function which makes it possible to enable Debugging output with -DOPENFLIPPER_SETTINGS_DEBUG...
double wheelZoomFactorShift()
Zoom factor when using mouse wheel and pressing shift.
void viewUpdated()
This signal is emitted when the scene is repainted due to any event.
void grabGLArea()
get all Mouse & Key Events for GlWidget
void initModelviewMatrix()
initialize modelview matrix to identity
Viewer::ViewerProperties & properties_
All properties for this viewer.
virtual void mousePressEvent(QGraphicsSceneMouseEvent *_event)
handle mouse press events
void drawCursor()
draw the cursor
void setCursor(const QCursor &_cursor)
Sets the current used cursor.
void set_projection(const GLMatrixd &_m)
set projection
virtual void setHome()
set home position
Vec3d eye() const
get eye point
int setupScene(int _viewerID, int _width, int _height, int _samples=0, int _stereoEye=-1)
Bind fbo for scene rendering.
void actionPasteView(QSize *_windowSize=NULL, int *_splitterWidth=NULL)
QSize glSize() const
get size of QGLWIdget
double ortho_width() const
Get width of the gl scene in orthogonal projection mode.
double fovyModifier_
mouse interaction position
static GLuint getFramebufferDraw()
get current draw framebuffer of a target
Vec3d project(const Vec3d &_point) const
project point in world coordinates to window coordinates
void viewWheelEvent(QWheelEvent *_event)
specialized viewer: handle wheel events
int viewport_height() const
get viewport height
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 cursorPositionValid()
Flag if stereo should be enabled for the current viewer.
static double clip(double _angle)
std::string pickMode()
get active pick mode
virtual void wheelEvent(QGraphicsSceneWheelEvent *_event)
handle mouse wheel events
void push_projection_matrix()
push projection matrix
ACG::Vec4f backgroundColor()
Get current background color.
void allow_multisampling(bool _b)
Disable multisampling globally.
QTime clickTime_
mouse interaction position
void setScenePos(const ACG::Vec3d &_center, double _radius, const bool _resetTrackBall=false)
ACG::Vec3d trackballCenter()
Get virtual trackball center (rotation center when using mouse)
void viewingDirection(const ACG::Vec3d &_dir, const ACG::Vec3d &_up)
set the viewing direction
void set_clear_color(const Vec4f &_col)
set background color
ChildIter find(BaseNode *_node)
use provided normals as is
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *_event)
handle mouse release events
void viewChanged()
This signal is emitted whenever the view is changed by the user.
void lookAt(const ACG::Vec3d &_eye, const ACG::Vec3d &_center, const ACG::Vec3d &_up)
Set look at transformation directly.