Developer Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
QtGLGraphicsScene.cc
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41 
42 /*===========================================================================*\
43 * *
44 * $Revision$ *
45 * $LastChangedBy$ *
46 * $Date$ *
47 * *
48 \*===========================================================================*/
49 
50 
51 
52 
53 //=============================================================================
54 //
55 // CLASS QtGLGraphicsScene - IMPLEMENTATION
56 //
57 //=============================================================================
58 
59 //== INCLUDES =================================================================
60 
61 #include <ACG/GL/acg_glew.hh>
63 #include "QtGLGraphicsScene.hh"
64 #include "QtMultiViewLayout.hh"
65 #include <QApplication>
66 #include <QPainter>
67 #include <QPaintEngine>
68 #include <QGraphicsSceneMouseEvent>
69 
70 //== NAMESPACES ===============================================================
71 
72 //== IMPLEMENTATION ===========================================================
73 
74 QtGLGraphicsScene::QtGLGraphicsScene(std::vector< glViewer *> *_views,
75  QtMultiViewLayout *_layout) :
76  QGraphicsScene (),
77  views_(_views),
78  layout_(_layout),
79  cursorPainter_(0)
80 {
81 }
82 
83 //-----------------------------------------------------------------------------
84 
85 void QtGLGraphicsScene::drawBackground(QPainter *_painter, const QRectF &_rect)
86 {
87  // Check for switch in qt4.6 to OpenGL2
88  #if QT_VERSION >= 0x040600
89  if (_painter->paintEngine()->type() != QPaintEngine::OpenGL && _painter->paintEngine()->type() != QPaintEngine::OpenGL2 ) {
90  std::cerr << "QtGLGraphicsScene: drawBackground needs a QGLWidget to be set as viewport on the graphics view\n";
91  return;
92  }
93  #else
94  if (_painter->paintEngine()->type() != QPaintEngine::OpenGL ) {
95  std::cerr << "QtGLGraphicsScene: drawBackground needs a QGLWidget to be set as viewport on the graphics view\n";
96  return;
97  }
98  #endif
99 
100  // Initialize background first
101  _painter->setBackground(QApplication::palette().window());
102  _painter->eraseRect(_rect);
103 
104  // From now on we do OpenGL direct painting on the scene
105  #if QT_VERSION >= 0x040600
106  // Tell Qt that we directly use OpenGL
107  _painter->beginNativePainting();
108  #endif
109 
110  static bool initialized = false;
111  if (!initialized)
112  {
113  // we use GLEW to manage extensions
114  // initialize it first
115  glewInit();
116  for (unsigned int i = 0; i < views_->size (); i++)
117  {
118  views_->at(i)->initializeGL ();
119  }
120  if (cursorPainter_)
121  cursorPainter_->initializeGL ();
122  initialized = true;
123  }
124 
125  // Update the cursor position in all viewers
126  if (cursorPainter_ && cursorPainter_->enabled())
127  {
128  // avoid projection matrix stack overflow
129  GLdouble mat[16];
130  glGetDoublev(GL_PROJECTION_MATRIX, mat);
131 
132  glMatrixMode(GL_MODELVIEW);
133  glPushMatrix ();
134 
135  glPushAttrib (GL_ALL_ATTRIB_BITS);
136  for (unsigned int i = 0; i < views_->size (); i++)
137  {
138  if (views_->at(i)->isVisible())
139  views_->at(i)->updateCursorPosition(cursorPainter_->cursorPosition ());
140  }
141  glPopAttrib ();
142 
143  glMatrixMode(GL_PROJECTION);
144  glLoadMatrixd (mat);
145  glMatrixMode(GL_MODELVIEW);
146  glPopMatrix ();
147  }
148 
149  // Clear the depth buffer (This is required since QT4.6 Otherwise we get an emtpty scene!
150  glClear(GL_DEPTH_BUFFER_BIT);
151 
152  // Paint the viewers
153  for (unsigned int i = 0; i < views_->size (); i++)
154  {
155  if (views_->at(i)->isVisible())
156  views_->at(i)->paintGL();
157  }
158 
159  #if QT_VERSION >= 0x040600
160  // The rest is painting through QT again.
161  _painter->endNativePainting();
162  #endif
163 
164  // Draw red box around active examiner
165  if (layout_->mode() != QtMultiViewLayout::SingleView)
166  {
167  glViewer *v = views_->at(PluginFunctions::activeExaminer());
168 
169  QPen pen(Qt::red);
170  pen.setWidth (2);
171  _painter->setPen(pen);
172  _painter->drawLine(v->scenePos().x(), v->scenePos().y(),
173  v->scenePos().x(),
174  v->scenePos().y() + v->size().height() - 1);
175  _painter->drawLine(v->scenePos().x() + v->size().width(), v->scenePos().y(),
176  v->scenePos().x() + v->size().width(),
177  v->scenePos().y() + v->size().height() - 1);
178  _painter->drawLine(v->scenePos().x(), v->scenePos().y() - 1,
179  v->scenePos().x() + v->size().width(),
180  v->scenePos().y() - 1);
181  _painter->drawLine(v->scenePos().x(),
182  v->scenePos().y() + v->size().height() - 1,
183  v->scenePos().x() + v->size().width(),
184  v->scenePos().y() + v->size().height() - 1);
185  }
186 }
187 
188 //-----------------------------------------------------------------------------
189 
190 glViewer* QtGLGraphicsScene::findView (const QPointF &_p, bool _setActive)
191 {
192  for (unsigned int i = 0; i < views_->size (); i++)
193  {
194  if (views_->at(i)->contains(views_->at(i)->mapFromScene (_p)))
195  {
196  if (_setActive && PluginFunctions::activeExaminer() != i)
197  {
199  update();
200  }
201  return views_->at(i);
202  }
203  }
204  return NULL;
205 }
206 
207 //-----------------------------------------------------------------------------
208 
209 void QtGLGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent* _e)
210 {
211  QGraphicsScene::mouseMoveEvent(_e);
212  if (_e->isAccepted())
213  return;
214 
215  glViewer *v = findView (_e->scenePos());
216  if (!v)
217  return;
218 
219  v->mouseMoveEvent(_e);
220 }
221 
222 //-----------------------------------------------------------------------------
223 
224 void QtGLGraphicsScene::setCursorPainter(CursorPainter * _cursorPainter)
225 {
226  cursorPainter_ = _cursorPainter;
227 }
228 
229 //-----------------------------------------------------------------------------
230 
231 bool QtGLGraphicsScene::event(QEvent *_event)
232 {
233  if (cursorPainter_ && _event->type() == QEvent::Enter)
234  {
235  cursorPainter_->setMouseIn (true);
236  }
237  else if (cursorPainter_ && _event->type() == QEvent::Leave)
238  {
239  cursorPainter_->setMouseIn (false);
240  update ();
241  }
242  else if (cursorPainter_ && _event->type() == QEvent::GraphicsSceneMouseMove)
243  {
244  QGraphicsSceneMouseEvent *e = static_cast<QGraphicsSceneMouseEvent*>(_event);
245  cursorPainter_->updateCursorPosition (e->scenePos ());
246  update ();
247  }
248 
249  return QGraphicsScene::event (_event);
250 }
251 
252 
253 //=============================================================================
254 //=============================================================================
255 
void setActiveExaminer(const unsigned int _id)
Set the active id of the examiner which got the last mouse events.
unsigned int activeExaminer()
Get the id of the examiner which got the last mouse events.
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *_event)
handle mouse move events