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 |