Main MRPT website > C++ reference
MRPT logo
COpenGLViewport.h
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | The Mobile Robot Programming Toolkit (MRPT) C++ library |
3  | |
4  | http://www.mrpt.org/ |
5  | |
6  | Copyright (C) 2005-2012 University of Malaga |
7  | |
8  | This software was written by the Machine Perception and Intelligent |
9  | Robotics Lab, University of Malaga (Spain). |
10  | Contact: Jose-Luis Blanco <jlblanco@ctima.uma.es> |
11  | |
12  | This file is part of the MRPT project. |
13  | |
14  | MRPT is free software: you can redistribute it and/or modify |
15  | it under the terms of the GNU General Public License as published by |
16  | the Free Software Foundation, either version 3 of the License, or |
17  | (at your option) any later version. |
18  | |
19  | MRPT is distributed in the hope that it will be useful, |
20  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
21  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
22  | GNU General Public License for more details. |
23  | |
24  | You should have received a copy of the GNU General Public License |
25  | along with MRPT. If not, see <http://www.gnu.org/licenses/>. |
26  | |
27  +---------------------------------------------------------------------------+ */
28 #ifndef opengl_COpenGLViewport_H
29 #define opengl_COpenGLViewport_H
30 
33 #include <mrpt/utils/CImage.h>
34 #include <mrpt/opengl/CCamera.h>
37 #include <mrpt/utils/CObservable.h>
38 
39 namespace mrpt
40 {
41  namespace utils { class CStringList; class CImage; }
42 
43  namespace opengl
44  {
45  using namespace mrpt::math;
46 
47  class COpenGLScene;
48  class CRenderizable;
49 
50  // This must be added to any CSerializable derived class:
52 
53  /** A viewport within a COpenGLScene, containing a set of OpenGL objects to render.
54  * This class has protected constuctor, thus it cannot be created by users. Use COpenGLScene::createViewport instead.
55  * A viewport has these "operation modes":
56  * - Normal (default): It renders the contained objects.
57  * - Cloned: It clones the objects from another viewport. See \a setCloneView()
58  * - Image mode: It renders an image (e.g. from a video stream) efficiently using a textued quad. See \a setImageView().
59  *
60  * In any case, the viewport can be resized to only fit a part of the entire parent viewport.
61  * There will be always at least one viewport in a COpenGLScene named "main".
62  *
63  * This class can be observed (see mrpt::utils::CObserver) for the following events (see mrpt::utils::mrptEvent):
64  * - mrpt::opengl::mrptEventGLPreRender
65  * - mrpt::opengl::mrptEventGLPostRender
66  *
67  * Refer to mrpt::opengl::COpenGLScene for further details.
68  * \ingroup mrpt_opengl_grp
69  */
71  public mrpt::utils::CSerializable,
72  public mrpt::utils::CObservable
73  {
75  friend class COpenGLScene;
76  public:
77  // -------------------------------------------------------------------
78  /** @name Set the viewport "modes"
79  @{ */
80 
81  /** Set this viewport as a clone of some other viewport, given its name - as a side effect, current list of internal OpenGL objects is cleared.
82  * By default, only the objects are cloned, not the camera. See
83  * \sa resetCloneView
84  */
85  void setCloneView( const std::string &clonedViewport );
86 
87  /** Set this viewport into "image view"-mode, where an image is efficiently drawn (fitting the viewport area) using an OpenGL textured quad.
88  * Call this method with the new image to update the displayed image (but recall to first lock the parent openglscene's critical section, then do the update, then release the lock, and then issue a window repaint).
89  * Internally, the texture is drawn using a mrpt::opengl::CTexturedPlane
90  * The viewport can be reverted to behave like a normal viewport by calling setNormalMode()
91  * \sa setImageView_fast
92  */
93  void setImageView(const mrpt::utils::CImage &img);
94 
95  /** Just like \a setImageView but moves the internal image memory instead of making a copy, so it's faster but empties the input image.
96  * \sa setImageView
97  */
98  void setImageView_fast(mrpt::utils::CImage &img);
99 
100  /** Reset the viewport to normal mode: rendering its own objects.
101  * \sa setCloneView, setNormalMode
102  */
103  inline void resetCloneView() { setNormalMode(); }
104 
105  /** If set to true, and setCloneView() has been called, this viewport will be rendered using the camera of the cloned viewport.
106  */
107  inline void setCloneCamera(bool enable) { m_isClonedCamera = enable; }
108 
109  /** Resets the viewport to a normal 3D viewport \sa setCloneView, setImageView */
110  void setNormalMode();
111 
112  /** @} */ // end of Set the "viewport mode"
113  // ------------------------------------------------------
114 
115 
116  // -------------------------------------------------------------------
117  /** @name Change or read viewport properties (except "viewport modes")
118  @{ */
119 
120  /** Returns the name of the viewport */
121  inline std::string getName() { return m_name; }
122 
123  /** Change the viewport position and dimension on the rendering window.
124  * X & Y coordinates here can have two interpretations:
125  * - If in the range [0,1], they are factors with respect to the actual window sizes (i.e. width=1 means the entire width of the rendering window).
126  * - If >1, they are interpreted as pixels.
127  *
128  * width & height can be interpreted as:
129  * - If >1, they are the size of the viewport in that dimension, in pixels.
130  * - If in [0,1], they are the size of the viewport in that dimension, in a factor of the width/height.
131  * - If in [-1,0[, the size is computed such as the right/top border ends up in the given coordinate, interpreted as a factor (e.g. -1: up to the end of the viewport, -0.5: up to the middle of it).
132  * - If <-1 the size is computed such as the right/top border ends up in the given absolute coordinate (e.g. -200: up to the row/column 200px).
133  *
134  * \note (x,y) specify the lower left corner of the viewport rectangle.
135  * \sa getViewportPosition
136  */
137  void setViewportPosition(
138  const double x,
139  const double y,
140  const double width,
141  const double height );
142 
143  /** Get the current viewport position and dimension on the rendering window.
144  * X & Y coordinates here can have two interpretations:
145  * - If in the range [0,1], they are factors with respect to the actual window sizes (i.e. width=1 means the entire width of the rendering window).
146  * - If >1, they are interpreted as pixels.
147  * \note (x,y) specify the lower left corner of the viewport rectangle.
148  * \sa setViewportPosition
149  */
150  void getViewportPosition(
151  double &x,
152  double &y,
153  double &width,
154  double &height );
155 
156  /** Set the min/max clip depth distances of the rendering frustum (default: 0.1 - 10000)
157  * \sa getViewportClipDistances
158  */
159  void setViewportClipDistances(const double clip_min, const double clip_max);
160 
161  /** Get the current min/max clip depth distances of the rendering frustum (default: 0.1 - 10000)
162  * \sa setViewportClipDistances
163  */
164  void getViewportClipDistances(double &clip_min, double &clip_max) const;
165 
166  /** Set the border size ("frame") of the viewport (default=0).
167  */
168  inline void setBorderSize( unsigned int lineWidth ) { m_borderWidth = lineWidth; }
169 
170  /** Return whether the viewport will be rendered transparent over previous viewports.
171  */
172  inline bool isTransparent() { return m_isTransparent; }
173 
174  /** Set the transparency, that is, whether the viewport will be rendered transparent over previous viewports (default=false).
175  */
176  inline void setTransparent( bool trans ) { m_isTransparent=trans; }
177 
178  /** Set a background color different from that of the parent GUI window */
179  inline void setCustomBackgroundColor( const TColorf &color ) { m_custom_backgb_color = true; m_background_color = color; }
180 
181  inline TColorf getCustomBackgroundColor() const { return m_background_color; }
182 
183  /** Compute the 3D ray corresponding to a given pixel; this can be used to allow the user to pick and select 3D objects by clicking onto the 2D image.
184  * \param x_coord Horizontal coordinate with the usual meaning (0:left of the viewport, W-1: right border).
185  * \param y_coord Horizontal coordinate with the usual meaning (0:top of the viewport, H-1: right border).
186  * \param out_cameraPose If not NULL, will have the camera 3D pose as a mrpt::poses::CPose3D. See also
187  * \note (x,y) refer to VIEWPORT coordinates. Take into account this when viewports do not extend to the whole window size.
188  * \note x and y are double instead of integers to allow sub-pixel precision.
189  * \sa getCurrentCameraPose
190  */
191  void get3DRayForPixelCoord( const double x_coord, const double y_coord, mrpt::math::TLine3D &out_ray, mrpt::poses::CPose3D *out_cameraPose=NULL ) const;
192 
193  /** @} */ // end of Change or read viewport properties
194  // ------------------------------------------------------
195 
196 
197  // -------------------------------------------------------------------
198  /** @name Contained objects set/get/search
199  @{ */
200 
203 
204  inline const_iterator begin() const { return m_objects.begin(); }
205  inline const_iterator end() const { return m_objects.end(); }
206  inline iterator begin() { return m_objects.begin(); }
207  inline iterator end() { return m_objects.end(); }
208 
209  /** Delete all internal obejcts
210  * \sa insert */
211  void clear();
212 
213  /** Insert a new object into the list.
214  * The object MUST NOT be deleted, it will be deleted automatically by this object when not required anymore.
215  */
216  void insert( const CRenderizablePtr &newObject );
217 
218  /** Compute the current 3D camera pose.
219  * \sa get3DRayForPixelCoord
220  */
221  void getCurrentCameraPose( mrpt::poses::CPose3D &out_cameraPose ) const;
222 
223  /** Returns the first object with a given name, or NULL if not found.
224  */
225  CRenderizablePtr getByName( const std::string &str );
226 
227  /** Returns the i'th object of a given class (or of a descendant class), or NULL (an empty smart pointer) if not found.
228  * Example:
229  * \code
230  CSpherePtr obs = view.getByClass<CSphere>();
231  * \endcode
232  * By default (ith=0), the first observation is returned.
233  */
234  template <typename T>
235  typename T::SmartPtr getByClass( const size_t &ith = 0 ) const
236  {
237  MRPT_START
238  size_t foundCount = 0;
239  const mrpt::utils::TRuntimeClassId* class_ID = T::classinfo;
240  for (CListOpenGLObjects::const_iterator it = m_objects.begin();it!=m_objects.end();++it)
241  if ( (*it).present() && (*it)->GetRuntimeClass()->derivedFrom( class_ID ) )
242  if (foundCount++ == ith)
243  return typename T::SmartPtr(*it);
244 
245  // If not found directly, search recursively:
246  for (CListOpenGLObjects::const_iterator it=m_objects.begin();it!=m_objects.end();++it)
247  {
248  if ( (*it).present() && (*it)->GetRuntimeClass() == CLASS_ID_NAMESPACE(CSetOfObjects,mrpt::opengl))
249  {
250  typename T::SmartPtr o = CSetOfObjectsPtr(*it)->getByClass<T>(ith);
251  if (o.present()) return o;
252  }
253  }
254  return typename T::SmartPtr(); // Not found: return empty smart pointer
255  MRPT_END
256  }
257 
258  /** Removes the given object from the scene (it also deletes the object to free its memory).
259  */
260  void removeObject( const CRenderizablePtr & obj );
261 
262  /** Number of objects contained. */
263  inline size_t size() const { return m_objects.size(); }
264 
265  inline bool empty() const { return m_objects.empty(); }
266 
267 
268  opengl::CCamera& getCamera() { return m_camera;} //!< Get a reference to the camera associated with this viewport.
269 
270  const opengl::CCamera & getCamera() const { return m_camera;} //!< Get a reference to the camera associated with this viewport.
271 
272  /** @} */ // end of Contained objects set/get/search
273  // ------------------------------------------------------
274 
275 
276  virtual ~COpenGLViewport(); //!< Destructor: clears all objects.
277 
278 
279  protected:
280  /** Constructor, invoked from COpenGLScene only.
281  */
282  COpenGLViewport( COpenGLScene *parent=NULL, const std::string &name=std::string("") );
283 
284  /** Initializes all textures in the scene (See opengl::CTexturedPlane::loadTextureInOpenGL)
285  */
286  void initializeAllTextures();
287 
288  /** Retrieves a list of all objects in text form.
289  */
290  void dumpListOfObjects( utils::CStringList &lst );
291 
292  /** Render the objects in this viewport (called from COpenGLScene only) */
293  void render( const int render_width, const int render_height ) const;
294 
295  /** The camera associated to the viewport */
297  utils::safe_ptr<COpenGLScene> m_parent; //!< The scene that contains this viewport.
298  bool m_isCloned; //!< Set by setCloneView
299  bool m_isClonedCamera; //!< Set by setCloneCamera
300  std::string m_clonedViewport; //!< Only if m_isCloned=true
301  std::string m_name; //!< The viewport's name
302  bool m_isTransparent; //!< Whether to clear color buffer.
303  uint32_t m_borderWidth; //!< Default=0, the border around the viewport.
304  double m_view_x, m_view_y,m_view_width,m_view_height; //!< The viewport position [0,1]
305  double m_clip_min,m_clip_max; //!< The min/max clip depth distances (default: 0.1 - 10000)
307  TColorf m_background_color; //!< used only if m_custom_backgb_color
308  bool m_isImageView; //!< Set by setImageView
309  //CRenderizablePtr m_imageview_quad ; //!< A mrpt::opengl::CTexturedPlane used after setImageView() is called
310  mrpt::utils::CImagePtr m_imageview_img; //!< The image to display, after calling \a setImageView()
311 
313  {
314  TLastProjectiveMatrixInfo() : is_projective(true),eye(0,0,0),pointing(0,0,0),up(0,0,0), FOV(30), viewport_width(640), viewport_height(480), azimuth(0), elev(0), zoom(1)
315  {}
316  bool is_projective; // true: projective, false: ortho
317  TPoint3D eye; //!< The camera is here.
318  TPoint3D pointing; //!< The camera points to here
319  TPoint3D up; //!< Up vector of the camera.
320  float FOV; //!< FOV in degrees.
321  size_t viewport_width, viewport_height; //!< In pixels. This may be smaller than the total render window.
322  float azimuth, elev; //!< Camera elev & azimuth, in radians.
323  float zoom;
324  };
325  mutable TLastProjectiveMatrixInfo m_lastProjMat; //!< Info updated with each "render()" and used in "get3DRayForPixelCoord"
326 
327  /** The list of objects that comprise the 3D scene.
328  * Objects are automatically deleted when calling "clear" or in the destructor.
329  */
331 
332  void internal_setImageView_fast(const mrpt::utils::CImage &img, bool is_fast);
333 
334  };
335  /**
336  * Inserts an openGL object into a viewport. Allows call chaining.
337  * \sa mrpt::opengl::COpenGLViewport::insert
338  */
340  s->insert(r);
341  return s;
342  }
343  /**
344  * Inserts any iterable set of openGL objects into a viewport. Allows call chaining.
345  * \sa mrpt::opengl::COpenGLViewport::insert
346  */
347  inline COpenGLViewportPtr &operator<<(COpenGLViewportPtr &s,const std::vector<CRenderizablePtr> &v) {
348  for (std::vector<CRenderizablePtr>::const_iterator it=v.begin();it!=v.end();++it) s->insert(*it);
349  return s;
350  }
351 
352 
353 
354  /** @name Events emitted by COpenGLViewport
355  @{ */
356 
357  /** An event sent by an mrpt::opengl::COpenGLViewport just after clearing the viewport and setting the GL_PROJECTION matrix, and before calling the scene OpenGL drawing primitives.
358  *
359  * While handling this event you can call OpenGL glBegin(),glEnd(),gl* functions or those in mrpt::opengl::gl_utils to draw stuff *in the back* of the normal
360  * objects contained in the COpenGLScene.
361  *
362  * After processing this event, COpenGLViewport will change the OpenGL matrix mode into "GL_MODELVIEW" and load an identity matrix to continue
363  * rendering the scene objects as usual. Any change done to the GL_PROJECTION will have effects, so do a glPushMatrix()/glPopMatrix() if that is not your intention.
364  *
365  *
366  * IMPORTANTE NOTICE: Event handlers in your observer class will most likely be invoked from an internal GUI thread of MRPT,
367  * so all your code in the handler must be thread safe.
368  */
370  {
371  protected:
372  virtual void do_nothing() { } //!< Just to allow this class to be polymorphic
373  public:
374  inline mrptEventGLPreRender(const COpenGLViewport* obj) : source_viewport(obj) { }
376  }; // End of class def.
377 
378  /** An event sent by an mrpt::opengl::COpenGLViewport after calling the scene OpenGL drawing primitives and before doing a glSwapBuffers
379  *
380  * While handling this event you can call OpenGL glBegin(),glEnd(),gl* functions or those in mrpt::opengl::gl_utils to draw stuff *on the top* of the normal
381  * objects contained in the COpenGLScene.
382  *
383  * IMPORTANTE NOTICE: Event handlers in your observer class will most likely be invoked from an internal GUI thread of MRPT,
384  * so all your code in the handler must be thread safe.
385  */
387  {
388  protected:
389  virtual void do_nothing() { } //!< Just to allow this class to be polymorphic
390  public:
391  inline mrptEventGLPostRender(const COpenGLViewport* obj) : source_viewport(obj) { }
393  }; // End of class def.
394 
395 
396  /** @} */
397 
398 
399 
400  } // end namespace
401 
402 } // End of namespace
403 
404 
405 #endif



Page generated by Doxygen 1.8.3 for MRPT 0.9.6 SVN: at Fri Feb 15 22:05:02 EST 2013