OpenWalnut  1.4.0
WGEOffscreenRenderNode.h
00001 //---------------------------------------------------------------------------
00002 //
00003 // Project: OpenWalnut ( http://www.openwalnut.org )
00004 //
00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
00006 // For more information see http://www.openwalnut.org/copying
00007 //
00008 // This file is part of OpenWalnut.
00009 //
00010 // OpenWalnut is free software: you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as published by
00012 // the Free Software Foundation, either version 3 of the License, or
00013 // (at your option) any later version.
00014 //
00015 // OpenWalnut is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 // GNU Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public License
00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
00022 //
00023 //---------------------------------------------------------------------------
00024 
00025 #ifndef WGEOFFSCREENRENDERNODE_H
00026 #define WGEOFFSCREENRENDERNODE_H
00027 
00028 #include <string>
00029 
00030 #include <osg/Camera>
00031 
00032 #include "core/common/WLogger.h"
00033 
00034 #include "../WGEGroupNode.h"
00035 #include "WGEOffscreenRenderPass.h"
00036 #include "WGEOffscreenTexturePass.h"
00037 #include "WGEOffscreenFinalPass.h"
00038 #include "../WGETextureHud.h"
00039 #include "../shaders/WGEShader.h"
00040 #include "../callbacks/WGEViewportCallback.h"
00041 
00042 /**
00043  * This type of node basically is a convenience class for managing and creating offscreen renderings. The children of this node should be of type
00044  * \ref WGEOffscreenRenderPass. This class provides factories to create offscreen-render-pass instances with proper sizes with a coupling to a
00045  * reference camera. This is useful to provide automatic viewport scaling etc. to each render-pass. You do not explicitly need this class to
00046  * create offscreen-renderings at all. You can manually manage multiple WGEOffscreenRenderPass instances.
00047  *
00048  * It is important to understand, that the graph (your scene) must not be a children of this node. This node can be placed somewhere in your
00049  * scene. The OSG collects all the cameras (and offscreen-cameras) and render then independently from their position in the graph (except for
00050  * transformations inherited from others).
00051  *
00052  * \note Please not that you should not modify the whole wiring and offscreen configuration if the this node has been added as it is not
00053  * thread-safe.
00054  */
00055 class WGEOffscreenRenderNode: public WGEGroupNode // NOLINT
00056 {
00057 public:
00058     /**
00059      * Convenience typedef for an osg::ref_ptr
00060      */
00061     typedef osg::ref_ptr< WGEOffscreenRenderNode > RefPtr;
00062 
00063     /**
00064      * Convenience typedef for an osg::ref_ptr; const
00065      */
00066     typedef osg::ref_ptr< const WGEOffscreenRenderNode > ConstRefPtr;
00067 
00068     /**
00069      * Create a new managing instance. It uses the specified camera as reference to all created offscreen-render-pass instances. Especially
00070      * viewport, clear-mask and clear-color get used. The default texture resolution is 2048x2048 which is more than full-HD resolution. So it
00071      * should be enough.
00072      *
00073      * \note The width and hight define the offscreen texture size. The viewport if each rendering is automatically set to the one of the
00074      * reference camera. This means, width and height only define the maximal supported resolution without upscaling of your offscreen renderer.
00075      *
00076      * \param reference camera used as reference
00077      * \param width the width of the textures used in this rendering. Must be in [8,4096] and a power of two.
00078      * \param height the height of the textures used in this rendering. Must be in [8,4096] and a power of two.
00079      *
00080      * \param noHud If true, no hud gets displayed showing the created and used textures.
00081      */
00082     WGEOffscreenRenderNode( osg::ref_ptr< WGECamera > reference, size_t width = 2048, size_t height = 2048, bool noHud = false );
00083 
00084     /**
00085      * Destructor.
00086      */
00087     virtual ~WGEOffscreenRenderNode();
00088 
00089     /**
00090      * Returns the instance of the texture HUD.
00091      *
00092      * \return the HUD
00093      */
00094     osg::ref_ptr< WGETextureHud > getTextureHUD() const;
00095 
00096     /**
00097      * Creates a new offscreen-render-pass coupled with the reference camera which renders a specified OSG graph to a texture.
00098      *
00099      * \param node the node which represents the subgraph.
00100      * \param name the name of the render pass. You should specify it to enable the nice debugging feature of WGETextureHud.
00101      *
00102      * \note never forget to remove the returned node if not used anymore or use WGEGroup::clean.
00103      *
00104      * \return the geometry render pass.
00105      */
00106     virtual osg::ref_ptr< WGEOffscreenRenderPass > addGeometryRenderPass( osg::ref_ptr< osg::Node > node, std::string name = "Unnamed" );
00107 
00108     /**
00109      * Creates a new offscreen-render-pass coupled with the reference camera which renders a specified OSG graph to a texture.
00110      *
00111      * \param node the node which represents the subgraph.
00112      * \param name the name of the render pass. You should specify it to enable the nice debugging feature of WGETextureHud.
00113      * \param shader the shader to add.
00114      *
00115      * \note never forget to remove the returned node if not used anymore or use WGEGroup::clean.
00116      *
00117      * \return the geometry render pass.
00118      */
00119     virtual osg::ref_ptr< WGEOffscreenRenderPass > addGeometryRenderPass( osg::ref_ptr< osg::Node > node, osg::ref_ptr< WGEShader > shader,
00120                                                                           std::string name = "Unnamed" );
00121 
00122     /**
00123      * Creates a new offscreen-render-pass coupled with the reference camera which simply processes textures. All the in- and output textures
00124      * have to be specified manually.
00125      *
00126      * \note never forget to remove the returned node if not used anymore or use WGEGroup::clean.
00127      *
00128      * \param name the name of the render pass. You should specify it to enable the nice debugging feature of WGETextureHud.
00129      *
00130      * \return the texture processing pass created.
00131      */
00132     virtual osg::ref_ptr< WGEOffscreenTexturePass > addTextureProcessingPass( std::string name = "Unnamed" );
00133 
00134     /**
00135      * Creates a new offscreen-render-pass coupled with the reference camera which simply processes textures. All the in- and output textures
00136      * have to be specified manually.
00137      *
00138      * \note never forget to remove the returned node if not used anymore or use WGEGroup::clean.
00139      *
00140      * \param name the name of the render pass. You should specify it to enable the nice debugging feature of WGETextureHud.
00141      * \param shader the shader to add.
00142      *
00143      * \return the texture processing pass created.
00144      */
00145     virtual osg::ref_ptr< WGEOffscreenTexturePass > addTextureProcessingPass( osg::ref_ptr< WGEShader > shader, std::string name = "Unnamed" );
00146 
00147     /**
00148      * Creates a new render pass which can be seen as put-textures-back-on-screen-pass. It renders a full-screen quad to the on-screen
00149      * frame-buffer. An optional shader can be used for final processing (most commonly clipping, blending, color-mapping and so on).
00150      *
00151      * \param name the name of the render pass. You should specify it to enable the nice debugging feature of WGETextureHud.
00152      *
00153      * \return the on-screen render pass which draws processed textures back on screen.
00154      */
00155     virtual osg::ref_ptr< WGEOffscreenFinalPass > addFinalOnScreenPass( std::string name = "Unnamed" );
00156 
00157     /**
00158      * Creates a new render pass which can be seen as put-textures-back-on-screen-pass. It renders a full-screen quad to the on-screen
00159      * frame-buffer. An optional shader can be used for final processing (most commonly clipping, blending, color-mapping and so on).
00160      *
00161      * \param shader the shader to add
00162      * \param name the name of the render pass. You should specify it to enable the nice debugging feature of WGETextureHud.
00163      *
00164      * \return the on-screen render pass which draws processed textures back on screen.
00165      */
00166     virtual osg::ref_ptr< WGEOffscreenFinalPass > addFinalOnScreenPass( osg::ref_ptr< WGEShader > shader, std::string name = "Unnamed" );
00167 
00168     /**
00169      * Creates a new offscreen-render-pass coupled with the reference camera. This pass actually does nothing. The method is useful for custom
00170      * variants of WGEOffscreenRenderPass.
00171      *
00172      * \param name the name of the render pass. You should specify it to enable the nice debugging feature of WGETextureHud.
00173      *
00174      * \return new instance of a plain render pass
00175      *
00176      * \tparam T the type of pass to create.
00177      */
00178     template < typename T >
00179     osg::ref_ptr< T >  addRenderPass( std::string name = "Unnamed" );
00180 
00181     /**
00182      * Get FBO texture width.
00183      *
00184      * \return the width
00185      */
00186     size_t getTextureWidth() const;
00187 
00188     /**
00189      * Get FBO texture height.
00190      *
00191      * \return the height
00192      */
00193     size_t getTextureHeight() const;
00194 
00195     /**
00196      * If true, the viewport has the size of the resulting texture. This is very interesting if you want to force large scale renderings and want
00197      * to decouple your offscreen pass from the reference camera viewport.
00198      *
00199      * \param vp if true, viewport is forced to be the whole texture size
00200      */
00201     void setLinkViewportToTextureSize( bool vp = true );
00202 
00203     /**
00204      * The flag denotes whether the viewport is linked to the texture size or the reference camera. See \ref setLinkViewportToTextureSize for
00205      * details.
00206      *
00207      * \return the flag.
00208      */
00209     bool getLinkViewportToTextureSize() const;
00210 
00211 protected:
00212 private:
00213     /**
00214      * The camera to which is used for setting this camera up.
00215      */
00216     osg::ref_ptr< WGECamera > m_referenceCamera;
00217 
00218     /**
00219      * The pointer to the hud used to render all used texture buffers. This can be NULL. It gets distributed to all created render-pass
00220      * instances.
00221      */
00222     osg::ref_ptr< WGETextureHud > m_hud;
00223 
00224     /**
00225      * The width of each texture in this offscreen rendering.
00226      */
00227     size_t m_textureWidth;
00228 
00229     /**
00230      * The height of each texture in this offscreen rendering.
00231      */
00232     size_t m_textureHeight;
00233 
00234     /**
00235      * The number of the next pass getting added.
00236      */
00237     size_t m_nextPassNum;
00238 
00239     /**
00240      * Flag denotes whether the viewport is coupled to the reference camera or the texture size
00241      */
00242     bool m_forceViewportTextureSize;
00243 };
00244 
00245 template < typename T >
00246 osg::ref_ptr< T > WGEOffscreenRenderNode::addRenderPass( std::string name )
00247 {
00248     // create a new pass
00249     osg::ref_ptr< T > pass = new T( m_textureWidth, m_textureHeight, m_hud, name, m_nextPassNum );
00250     m_nextPassNum++;
00251 
00252     // ensure proper propagation of viewport changes
00253     if( m_forceViewportTextureSize )
00254     {
00255         pass->addUpdateCallback( new WGEViewportCallback< T >( m_textureWidth, m_textureHeight ) );
00256     }
00257     else
00258     {
00259         pass->addUpdateCallback( new WGEViewportCallback< T >( m_referenceCamera ) );
00260     }
00261 
00262     // set clear mask and color according to reference cam
00263     pass->setClearMask( m_referenceCamera->getClearMask() );
00264     pass->setClearColor( m_referenceCamera->getClearColor() );
00265 
00266     // inherit cull settings
00267     pass->setCullSettings( *m_referenceCamera );
00268 
00269     pass->setComputeNearFarMode( osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR );
00270     pass->setNearFarRatio( 0.000001 );
00271     pass->setCullingMode( osg::CullSettings::NO_CULLING );
00272 
00273     // this node needs to keep all the pass instances. Only this way, the OSG traverses and renders these nodes in the order specified by
00274     // m_nextPassNum.
00275     insert( pass );   // insert into this group
00276 
00277     return pass;
00278 }
00279 
00280 #endif  // WGEOFFSCREENRENDERNODE_H
00281