Main MRPT website > C++ reference
MRPT logo
COpenGLViewport.h
Go to the documentation of this file.
00001 /* +---------------------------------------------------------------------------+
00002    |          The Mobile Robot Programming Toolkit (MRPT) C++ library          |
00003    |                                                                           |
00004    |                       http://www.mrpt.org/                                |
00005    |                                                                           |
00006    |   Copyright (C) 2005-2011  University of Malaga                           |
00007    |                                                                           |
00008    |    This software was written by the Machine Perception and Intelligent    |
00009    |      Robotics Lab, University of Malaga (Spain).                          |
00010    |    Contact: Jose-Luis Blanco  <jlblanco@ctima.uma.es>                     |
00011    |                                                                           |
00012    |  This file is part of the MRPT project.                                   |
00013    |                                                                           |
00014    |     MRPT is free software: you can redistribute it and/or modify          |
00015    |     it under the terms of the GNU General Public License as published by  |
00016    |     the Free Software Foundation, either version 3 of the License, or     |
00017    |     (at your option) any later version.                                   |
00018    |                                                                           |
00019    |   MRPT is distributed in the hope that it will be useful,                 |
00020    |     but WITHOUT ANY WARRANTY; without even the implied warranty of        |
00021    |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         |
00022    |     GNU General Public License for more details.                          |
00023    |                                                                           |
00024    |     You should have received a copy of the GNU General Public License     |
00025    |     along with MRPT.  If not, see <http://www.gnu.org/licenses/>.         |
00026    |                                                                           |
00027    +---------------------------------------------------------------------------+ */
00028 #ifndef opengl_COpenGLViewport_H
00029 #define opengl_COpenGLViewport_H
00030 
00031 #include <mrpt/utils/CSerializable.h>
00032 #include <mrpt/utils/safe_pointers.h>
00033 #include <mrpt/utils/CImage.h>
00034 #include <mrpt/opengl/CCamera.h>
00035 #include <mrpt/opengl/CSetOfObjects.h>
00036 #include <mrpt/math/lightweight_geom_data.h>
00037 #include <mrpt/utils/CObservable.h>
00038 
00039 namespace mrpt
00040 {
00041         namespace utils { class CStringList; class CImage; }
00042 
00043         namespace opengl
00044         {
00045                 using namespace mrpt::math;
00046 
00047                 class COpenGLScene;
00048                 class CRenderizable;
00049 
00050                 // This must be added to any CSerializable derived class:
00051                 DEFINE_SERIALIZABLE_PRE_CUSTOM_BASE_LINKAGE( COpenGLViewport, mrpt::utils::CSerializable, OPENGL_IMPEXP )
00052 
00053                 /** A viewport within a COpenGLScene, containing a set of OpenGL objects to render.
00054                   *   This class has protected constuctor, thus it cannot be created by users. Use COpenGLScene::createViewport instead.
00055                   *  A viewport has these "operation modes":
00056                   *             - Normal (default): It renders the contained objects.
00057                   *             - Cloned: It clones the objects from another viewport. See \a setCloneView()
00058                   *             - Image mode: It renders an image (e.g. from a video stream) efficiently using a textued quad. See \a setImageView().
00059                   *
00060                   * In any case, the viewport can be resized to only fit a part of the entire parent viewport.
00061                   *  There will be always at least one viewport in a COpenGLScene named "main".
00062                   *
00063                   * This class can be observed (see mrpt::utils::CObserver) for the following events (see mrpt::utils::mrptEvent):
00064                   *   - mrpt::opengl::mrptEventGLPreRender
00065                   *   - mrpt::opengl::mrptEventGLPostRender
00066                   *
00067                   *  Refer to mrpt::opengl::COpenGLScene for further details.
00068                   * \ingroup mrpt_opengl_grp
00069                   */
00070                 class OPENGL_IMPEXP COpenGLViewport :
00071                         public mrpt::utils::CSerializable,
00072                         public mrpt::utils::CObservable
00073                 {
00074                         DEFINE_SERIALIZABLE( COpenGLViewport )
00075                         friend class COpenGLScene;
00076                 public:
00077                         // -------------------------------------------------------------------
00078                         /** @name Set the viewport "modes"
00079                             @{ */
00080 
00081                         /** 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.
00082                           *  By default, only the objects are cloned, not the camera. See
00083                           * \sa resetCloneView
00084                           */
00085                         void setCloneView( const std::string &clonedViewport );
00086 
00087                         /** Set this viewport into "image view"-mode, where an image is efficiently drawn (fitting the viewport area) using an OpenGL textured quad.
00088                           *  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).
00089                           *  Internally, the texture is drawn using a mrpt::opengl::CTexturedPlane
00090                           *  The viewport can be reverted to behave like a normal viewport by calling setNormalMode()
00091                           * \sa setImageView_fast
00092                           */
00093                         void setImageView(const mrpt::utils::CImage &img);
00094 
00095                         /** Just like \a setImageView but moves the internal image memory instead of making a copy, so it's faster but empties the input image.
00096                           * \sa setImageView
00097                           */
00098                         void setImageView_fast(mrpt::utils::CImage &img);
00099 
00100                         /** Reset the viewport to normal mode: rendering its own objects.
00101                           * \sa setCloneView, setNormalMode
00102                           */
00103                         inline void resetCloneView() { setNormalMode(); }
00104 
00105                         /** If set to true, and setCloneView() has been called, this viewport will be rendered using the camera of the cloned viewport.
00106                           */
00107                         inline void setCloneCamera(bool enable) { m_isClonedCamera = enable; }
00108 
00109                         /** Resets the viewport to a normal 3D viewport \sa setCloneView, setImageView */
00110                         void setNormalMode();
00111 
00112                         /** @} */ // end of Set the "viewport mode"
00113                         // ------------------------------------------------------
00114 
00115 
00116                         // -------------------------------------------------------------------
00117                         /** @name Change or read viewport properties (except "viewport modes")
00118                             @{ */
00119 
00120                         /** Returns the name of the viewport */
00121                         inline std::string getName() { return m_name; }
00122 
00123                         /** Change the viewport position and dimension on the rendering window.
00124                           *  X & Y coordinates here can have two interpretations:
00125                           *    - 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).
00126                           *    - If >1, they are interpreted as pixels.
00127                           *
00128                           *  width & height can be interpreted as:
00129                           *             - If >1, they are the size of the viewport in that dimension, in pixels.
00130                           *             - If in [0,1], they are the size of the viewport in that dimension, in a factor of the width/height.
00131                           *             - 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).
00132                           *             - 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).
00133                           *
00134                           * \note (x,y) specify the lower left corner of the viewport rectangle.
00135                           * \sa getViewportPosition
00136                           */
00137                         void setViewportPosition(
00138                                 const double x,
00139                                 const double y,
00140                                 const double width,
00141                                 const double height );
00142 
00143                         /** Get the current viewport position and dimension on the rendering window.
00144                           *  X & Y coordinates here can have two interpretations:
00145                           *    - 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).
00146                           *    - If >1, they are interpreted as pixels.
00147                           * \note (x,y) specify the lower left corner of the viewport rectangle.
00148                           * \sa setViewportPosition
00149                           */
00150                         void getViewportPosition(
00151                                 double &x,
00152                                 double &y,
00153                                 double &width,
00154                                 double &height );
00155 
00156                         /** Set the min/max clip depth distances of the rendering frustum (default: 0.1 - 10000)
00157                           * \sa getViewportClipDistances
00158                           */
00159                         void setViewportClipDistances(const double clip_min, const double clip_max);
00160 
00161                         /** Get the current min/max clip depth distances of the rendering frustum (default: 0.1 - 10000)
00162                           * \sa setViewportClipDistances
00163                           */
00164                         void getViewportClipDistances(double &clip_min, double &clip_max) const;
00165 
00166                         /** Set the border size ("frame") of the viewport (default=0).
00167                           */
00168                         inline void setBorderSize( unsigned int lineWidth ) { m_borderWidth = lineWidth; }
00169 
00170                         /** Return whether the viewport will be rendered transparent over previous viewports.
00171                           */
00172                         inline bool isTransparent() { return m_isTransparent; }
00173 
00174                         /** Set the transparency, that is, whether the viewport will be rendered transparent over previous viewports (default=false).
00175                           */
00176                         inline void setTransparent( bool trans ) { m_isTransparent=trans; }
00177 
00178                         /** Set a background color different from that of the parent GUI window */
00179                         inline void setCustomBackgroundColor( const TColorf &color ) { m_custom_backgb_color = true; m_background_color = color; }
00180 
00181                         inline bool hasCustomBackgroundColor() const { return m_custom_backgb_color; }
00182 
00183                         inline TColorf getCustomBackgroundColor() const { return m_background_color; }
00184 
00185                         /** 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.
00186                           *  \param x_coord Horizontal coordinate with the usual meaning (0:left of the viewport, W-1: right border).
00187                           *  \param y_coord Horizontal coordinate with the usual meaning (0:top of the viewport, H-1: right border).
00188                           * \param out_cameraPose If not NULL, will have the camera 3D pose as a mrpt::poses::CPose3D. See also
00189                           * \note (x,y) refer to VIEWPORT coordinates. Take into account this when viewports do not extend to the whole window size.
00190                           * \note x and y are double instead of integers to allow sub-pixel precision.
00191                           * \sa getCurrentCameraPose
00192                           */
00193                         void get3DRayForPixelCoord( const double x_coord, const double y_coord, mrpt::math::TLine3D &out_ray, mrpt::poses::CPose3D *out_cameraPose=NULL ) const;
00194 
00195                         /** @} */ // end of Change or read viewport properties
00196                         // ------------------------------------------------------
00197 
00198 
00199                         // -------------------------------------------------------------------
00200                         /** @name Contained objects set/get/search
00201                             @{ */
00202 
00203                         typedef CListOpenGLObjects::const_iterator      const_iterator;
00204                         typedef CListOpenGLObjects::iterator            iterator;
00205 
00206                         inline const_iterator begin() const { return  m_objects.begin(); }
00207                         inline const_iterator end() const { return  m_objects.end(); }
00208                         inline iterator begin() { return  m_objects.begin(); }
00209                         inline iterator end() { return  m_objects.end(); }
00210 
00211                         /** Delete all internal obejcts
00212                           * \sa insert */
00213                         void clear();
00214 
00215                         /** Insert a new object into the list.
00216                           *  The object MUST NOT be deleted, it will be deleted automatically by this object when not required anymore.
00217                           */
00218                         void insert( const CRenderizablePtr &newObject );
00219 
00220                         /** Compute the current 3D camera pose.
00221                           * \sa get3DRayForPixelCoord
00222                           */
00223                         void getCurrentCameraPose( mrpt::poses::CPose3D &out_cameraPose ) const;
00224 
00225                         /** Returns the first object with a given name, or NULL if not found.
00226                           */
00227                         CRenderizablePtr getByName( const std::string &str );
00228 
00229                          /** Returns the i'th object of a given class (or of a descendant class), or NULL (an empty smart pointer) if not found.
00230                            *  Example:
00231                            * \code
00232                                         CSpherePtr obs = view.getByClass<CSphere>();
00233                            * \endcode
00234                            * By default (ith=0), the first observation is returned.
00235                            */
00236                          template <typename T>
00237                          typename T::SmartPtr getByClass( const size_t &ith = 0 ) const
00238                          {
00239                                 MRPT_START
00240                                 size_t  foundCount = 0;
00241                                 const mrpt::utils::TRuntimeClassId*     class_ID = T::classinfo;
00242                                 for (CListOpenGLObjects::const_iterator it = m_objects.begin();it!=m_objects.end();++it)
00243                                         if ( (*it).present() &&  (*it)->GetRuntimeClass()->derivedFrom( class_ID ) )
00244                                                 if (foundCount++ == ith)
00245                                                         return typename T::SmartPtr(*it);
00246 
00247                                 // If not found directly, search recursively:
00248                                 for (CListOpenGLObjects::const_iterator it=m_objects.begin();it!=m_objects.end();++it)
00249                                 {
00250                                         if ( (*it).present() && (*it)->GetRuntimeClass() == CLASS_ID_NAMESPACE(CSetOfObjects,mrpt::opengl))
00251                                         {
00252                                                 typename T::SmartPtr  o = CSetOfObjectsPtr(*it)->getByClass<T>(ith);
00253                                                 if (o.present()) return o;
00254                                         }
00255                                 }
00256                                 return typename T::SmartPtr();  // Not found: return empty smart pointer
00257                                 MRPT_END
00258                          }
00259 
00260                         /** Removes the given object from the scene (it also deletes the object to free its memory).
00261                           */
00262                         void removeObject( const CRenderizablePtr & obj );
00263 
00264                         /** Number of objects contained. */
00265                         inline size_t  size() const { return m_objects.size(); }
00266 
00267                         inline bool empty() const { return m_objects.empty(); }
00268 
00269 
00270                         opengl::CCamera& getCamera() { return m_camera;} //!< Get a reference to the camera associated with this viewport.
00271 
00272                         const opengl::CCamera & getCamera() const { return m_camera;} //!< Get a reference to the camera associated with this viewport.
00273 
00274                         /** @} */ // end of Contained objects set/get/search
00275                         // ------------------------------------------------------
00276 
00277 
00278                         virtual ~COpenGLViewport();  //!< Destructor: clears all objects.
00279 
00280 
00281                 protected:
00282                         /** Constructor, invoked from COpenGLScene only.
00283                           */
00284                         COpenGLViewport( COpenGLScene *parent=NULL, const std::string &name=std::string("") );
00285 
00286                         /** Initializes all textures in the scene (See opengl::CTexturedPlane::loadTextureInOpenGL)
00287                           */
00288                         void  initializeAllTextures();
00289 
00290                         /** Retrieves a list of all objects in text form.
00291                           */
00292                         void dumpListOfObjects( utils::CStringList  &lst );
00293 
00294                         /** Render the objects in this viewport (called from COpenGLScene only) */
00295                         void  render( const int render_width, const int render_height ) const;
00296 
00297                         /** The camera associated to the viewport */
00298                         opengl::CCamera         m_camera;
00299                         utils::safe_ptr<COpenGLScene>  m_parent;   //!< The scene that contains this viewport.
00300                         bool                    m_isCloned; //!< Set by setCloneView
00301                         bool                    m_isClonedCamera; //!< Set by setCloneCamera
00302                         std::string             m_clonedViewport; //!< Only if m_isCloned=true
00303                         std::string             m_name; //!< The viewport's name
00304                         bool                    m_isTransparent; //!< Whether to clear color buffer.
00305                         uint32_t        m_borderWidth;  //!< Default=0, the border around the viewport.
00306                         double                  m_view_x, m_view_y,m_view_width,m_view_height; //!< The viewport position [0,1]
00307                         double                  m_clip_min,m_clip_max; //!< The min/max clip depth distances (default: 0.1 - 10000)
00308                         bool                    m_custom_backgb_color;
00309                         TColorf                 m_background_color;  //!< used only if m_custom_backgb_color
00310                         bool                    m_isImageView; //!< Set by setImageView
00311                         //CRenderizablePtr m_imageview_quad ; //!< A mrpt::opengl::CTexturedPlane used after setImageView() is called
00312                         mrpt::utils::CImagePtr  m_imageview_img; //!< The image to display, after calling \a setImageView()
00313 
00314                         struct TLastProjectiveMatrixInfo
00315                         {
00316                                 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)
00317                                 {}
00318                                 bool is_projective;  // true: projective, false: ortho
00319                                 TPoint3D        eye;            //!< The camera is here.
00320                                 TPoint3D        pointing;       //!< The camera points to here
00321                                 TPoint3D        up;             //!< Up vector of the camera.
00322                                 float FOV; //!< FOV in degrees.
00323                                 size_t viewport_width, viewport_height; //!< In pixels. This may be smaller than the total render window.
00324                                 float azimuth, elev; //!< Camera elev & azimuth, in radians.
00325                                 float zoom;
00326                         };
00327                         mutable TLastProjectiveMatrixInfo m_lastProjMat;  //!< Info updated with each "render()" and used in "get3DRayForPixelCoord"
00328 
00329                         /** The list of objects that comprise the 3D scene.
00330                           *  Objects are automatically deleted when calling "clear" or in the destructor.
00331                           */
00332                         opengl::CListOpenGLObjects              m_objects;
00333 
00334                         void internal_setImageView_fast(const mrpt::utils::CImage &img, bool is_fast);
00335 
00336                 };
00337                 /**
00338                   * Inserts an openGL object into a viewport. Allows call chaining.
00339                   * \sa mrpt::opengl::COpenGLViewport::insert
00340                   */
00341                 inline COpenGLViewportPtr &operator<<(COpenGLViewportPtr &s,const CRenderizablePtr &r)  {
00342                         s->insert(r);
00343                         return s;
00344                 }
00345                 /**
00346                   * Inserts any iterable set of openGL objects into a viewport. Allows call chaining.
00347                   * \sa mrpt::opengl::COpenGLViewport::insert
00348                   */
00349                 inline COpenGLViewportPtr &operator<<(COpenGLViewportPtr &s,const std::vector<CRenderizablePtr> &v)     {
00350                         for (std::vector<CRenderizablePtr>::const_iterator it=v.begin();it!=v.end();++it) s->insert(*it);
00351                         return s;
00352                 }
00353 
00354 
00355 
00356                 /** @name Events emitted by COpenGLViewport
00357                         @{  */
00358 
00359                 /**  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.
00360                   *
00361                   *  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
00362                   *   objects contained in the COpenGLScene.
00363                   *
00364                   *  After processing this event, COpenGLViewport will change the OpenGL matrix mode into "GL_MODELVIEW" and load an identity matrix to continue
00365                   *   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.
00366                   *
00367                   *
00368                   *  IMPORTANTE NOTICE: Event handlers in your observer class will most likely be invoked from an internal GUI thread of MRPT,
00369                   *    so all your code in the handler must be thread safe.
00370                   */
00371                 class OPENGL_IMPEXP mrptEventGLPreRender : public mrptEvent
00372                 {
00373                 protected:
00374                         virtual void do_nothing() { } //!< Just to allow this class to be polymorphic
00375                 public:
00376                         inline mrptEventGLPreRender(const COpenGLViewport* obj) : source_viewport(obj) { }
00377                         const COpenGLViewport * const source_viewport;
00378                 }; // End of class def.
00379 
00380                 /**  An event sent by an mrpt::opengl::COpenGLViewport after calling the scene OpenGL drawing primitives and before doing a glSwapBuffers
00381                   *
00382                   *  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
00383                   *   objects contained in the COpenGLScene.
00384                   *
00385                   *  IMPORTANTE NOTICE: Event handlers in your observer class will most likely be invoked from an internal GUI thread of MRPT,
00386                   *    so all your code in the handler must be thread safe.
00387                   */
00388                 class OPENGL_IMPEXP mrptEventGLPostRender : public mrptEvent
00389                 {
00390                 protected:
00391                         virtual void do_nothing() { } //!< Just to allow this class to be polymorphic
00392                 public:
00393                         inline mrptEventGLPostRender(const COpenGLViewport* obj) : source_viewport(obj) { }
00394                         const COpenGLViewport * const source_viewport;
00395                 }; // End of class def.
00396 
00397 
00398                 /** @} */
00399 
00400 
00401 
00402         } // end namespace
00403 
00404 } // End of namespace
00405 
00406 
00407 #endif



Page generated by Doxygen 1.7.5 for MRPT 0.9.5 SVN: at Thu Oct 13 21:25:36 UTC 2011