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